From 98cfda4a9c4ba6caed1b2cfa145b361998dc5973 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Sun, 19 May 2024 19:21:11 +0200 Subject: [PATCH] plugin/jpeg: Upgraded to 9f --- uppsrc/plugin/jpg/lib/cdjpeg.c | 181 --------- uppsrc/plugin/jpg/lib/cjpegalt.c | 4 +- uppsrc/plugin/jpg/lib/ckconfig.c | 402 ------------------- uppsrc/plugin/jpg/lib/djpeg.c | 631 ----------------------------- uppsrc/plugin/jpg/lib/djpegalt.c | 4 +- uppsrc/plugin/jpg/lib/example.c | 433 -------------------- uppsrc/plugin/jpg/lib/jccoefct.c | 8 +- uppsrc/plugin/jpg/lib/jccolor.c | 35 +- uppsrc/plugin/jpg/lib/jchuff.c | 284 +++++++------- uppsrc/plugin/jpg/lib/jconfig.h | 21 +- uppsrc/plugin/jpg/lib/jdatadst.c | 16 +- uppsrc/plugin/jpg/lib/jdatasrc.c | 23 +- uppsrc/plugin/jpg/lib/jdcolor.c | 93 ++--- uppsrc/plugin/jpg/lib/jdct.h | 4 +- uppsrc/plugin/jpg/lib/jdmerge.c | 31 +- uppsrc/plugin/jpg/lib/jinclude.h | 66 +++- uppsrc/plugin/jpg/lib/jmemansi.c | 6 +- uppsrc/plugin/jpg/lib/jmemdos.c | 638 ------------------------------ uppsrc/plugin/jpg/lib/jmemmac.c | 289 -------------- uppsrc/plugin/jpg/lib/jmemname.c | 276 ------------- uppsrc/plugin/jpg/lib/jmemnobs.c | 113 ------ uppsrc/plugin/jpg/lib/jmorecfg.h | 31 +- uppsrc/plugin/jpg/lib/jpeglib.h | 4 +- uppsrc/plugin/jpg/lib/jpegtran.c | 654 ------------------------------- uppsrc/plugin/jpg/lib/jversion.h | 6 +- uppsrc/plugin/jpg/lib/rdjpgcom.c | 515 ------------------------ uppsrc/plugin/jpg/lib/transupp.c | 37 +- uppsrc/plugin/jpg/lib/wrjpgcom.c | 599 ---------------------------- 28 files changed, 375 insertions(+), 5029 deletions(-) delete mode 100644 uppsrc/plugin/jpg/lib/cdjpeg.c delete mode 100644 uppsrc/plugin/jpg/lib/ckconfig.c delete mode 100644 uppsrc/plugin/jpg/lib/djpeg.c delete mode 100644 uppsrc/plugin/jpg/lib/example.c delete mode 100644 uppsrc/plugin/jpg/lib/jmemdos.c delete mode 100644 uppsrc/plugin/jpg/lib/jmemmac.c delete mode 100644 uppsrc/plugin/jpg/lib/jmemname.c delete mode 100644 uppsrc/plugin/jpg/lib/jmemnobs.c delete mode 100644 uppsrc/plugin/jpg/lib/jpegtran.c delete mode 100644 uppsrc/plugin/jpg/lib/rdjpgcom.c delete mode 100644 uppsrc/plugin/jpg/lib/wrjpgcom.c diff --git a/uppsrc/plugin/jpg/lib/cdjpeg.c b/uppsrc/plugin/jpg/lib/cdjpeg.c deleted file mode 100644 index b6250ff97..000000000 --- a/uppsrc/plugin/jpg/lib/cdjpeg.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * cdjpeg.c - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains common support routines used by the IJG application - * programs (cjpeg, djpeg, jpegtran). - */ - -#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ -#include /* to declare isupper(), tolower() */ -#ifdef NEED_SIGNAL_CATCHER -#include /* to declare signal() */ -#endif -#ifdef USE_SETMODE -#include /* to declare setmode()'s parameter macros */ -/* If you have setmode() but not , just delete this line: */ -#include /* to declare setmode() */ -#endif - - -/* - * Signal catcher to ensure that temporary files are removed before aborting. - * NB: for Amiga Manx C this is actually a global routine named _abort(); - * we put "#define signal_catcher _abort" in jconfig.h. Talk about bogus... - */ - -#ifdef NEED_SIGNAL_CATCHER - -static j_common_ptr sig_cinfo; - -void /* must be global for Manx C */ -signal_catcher (int signum) -{ - if (sig_cinfo != NULL) { - if (sig_cinfo->err != NULL) /* turn off trace output */ - sig_cinfo->err->trace_level = 0; - jpeg_destroy(sig_cinfo); /* clean up memory allocation & temp files */ - } - exit(EXIT_FAILURE); -} - - -GLOBAL(void) -enable_signal_catcher (j_common_ptr cinfo) -{ - sig_cinfo = cinfo; -#ifdef SIGINT /* not all systems have SIGINT */ - signal(SIGINT, signal_catcher); -#endif -#ifdef SIGTERM /* not all systems have SIGTERM */ - signal(SIGTERM, signal_catcher); -#endif -} - -#endif - - -/* - * Optional progress monitor: display a percent-done figure on stderr. - */ - -#ifdef PROGRESS_REPORT - -METHODDEF(void) -progress_monitor (j_common_ptr cinfo) -{ - cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress; - int total_passes = prog->pub.total_passes + prog->total_extra_passes; - int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit); - - if (percent_done != prog->percent_done) { - prog->percent_done = percent_done; - if (total_passes > 1) { - fprintf(stderr, "\rPass %d/%d: %3d%% ", - prog->pub.completed_passes + prog->completed_extra_passes + 1, - total_passes, percent_done); - } else { - fprintf(stderr, "\r %3d%% ", percent_done); - } - fflush(stderr); - } -} - - -GLOBAL(void) -start_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress) -{ - /* Enable progress display, unless trace output is on */ - if (cinfo->err->trace_level == 0) { - progress->pub.progress_monitor = progress_monitor; - progress->completed_extra_passes = 0; - progress->total_extra_passes = 0; - progress->percent_done = -1; - cinfo->progress = &progress->pub; - } -} - - -GLOBAL(void) -end_progress_monitor (j_common_ptr cinfo) -{ - /* Clear away progress display */ - if (cinfo->err->trace_level == 0) { - fprintf(stderr, "\r \r"); - fflush(stderr); - } -} - -#endif - - -/* - * Case-insensitive matching of possibly-abbreviated keyword switches. - * keyword is the constant keyword (must be lower case already), - * minchars is length of minimum legal abbreviation. - */ - -GLOBAL(boolean) -keymatch (char * arg, const char * keyword, int minchars) -{ - register int ca, ck; - register int nmatched = 0; - - while ((ca = *arg++) != '\0') { - if ((ck = *keyword++) == '\0') - return FALSE; /* arg longer than keyword, no good */ - if (isupper(ca)) /* force arg to lcase (assume ck is already) */ - ca = tolower(ca); - if (ca != ck) - return FALSE; /* no good */ - nmatched++; /* count matched characters */ - } - /* reached end of argument; fail if it's too short for unique abbrev */ - if (nmatched < minchars) - return FALSE; - return TRUE; /* A-OK */ -} - - -/* - * Routines to establish binary I/O mode for stdin and stdout. - * Non-Unix systems often require some hacking to get out of text mode. - */ - -GLOBAL(FILE *) -read_stdin (void) -{ - FILE * input_file = stdin; - -#ifdef USE_SETMODE /* need to hack file mode? */ - setmode(fileno(stdin), O_BINARY); -#endif -#ifdef USE_FDOPEN /* need to re-open in binary mode? */ - if ((input_file = fdopen(fileno(stdin), READ_BINARY)) == NULL) { - fprintf(stderr, "Cannot reopen stdin\n"); - exit(EXIT_FAILURE); - } -#endif - return input_file; -} - - -GLOBAL(FILE *) -write_stdout (void) -{ - FILE * output_file = stdout; - -#ifdef USE_SETMODE /* need to hack file mode? */ - setmode(fileno(stdout), O_BINARY); -#endif -#ifdef USE_FDOPEN /* need to re-open in binary mode? */ - if ((output_file = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { - fprintf(stderr, "Cannot reopen stdout\n"); - exit(EXIT_FAILURE); - } -#endif - return output_file; -} diff --git a/uppsrc/plugin/jpg/lib/cjpegalt.c b/uppsrc/plugin/jpg/lib/cjpegalt.c index 4f35b04bf..c89827e26 100644 --- a/uppsrc/plugin/jpg/lib/cjpegalt.c +++ b/uppsrc/plugin/jpg/lib/cjpegalt.c @@ -2,7 +2,7 @@ * alternate cjpeg.c * * Copyright (C) 1991-1998, Thomas G. Lane. - * Modified 2009-2020 by Guido Vollbeding. + * Modified 2009-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -72,7 +72,7 @@ unused_dos_memory (void) #endif /* MSDOS */ -#ifdef ATARI /* For Atari ST/STE/TT, Pure C or Turbo C */ +#ifdef ATARI /* For Atari ST/Mega/STE/TT/Falcon, Pure C or Turbo C */ #include diff --git a/uppsrc/plugin/jpg/lib/ckconfig.c b/uppsrc/plugin/jpg/lib/ckconfig.c deleted file mode 100644 index e658623fa..000000000 --- a/uppsrc/plugin/jpg/lib/ckconfig.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * ckconfig.c - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - */ - -/* - * This program is intended to help you determine how to configure the JPEG - * software for installation on a particular system. The idea is to try to - * compile and execute this program. If your compiler fails to compile the - * program, make changes as indicated in the comments below. Once you can - * compile the program, run it, and it will produce a "jconfig.h" file for - * your system. - * - * As a general rule, each time you try to compile this program, - * pay attention only to the *first* error message you get from the compiler. - * Many C compilers will issue lots of spurious error messages once they - * have gotten confused. Go to the line indicated in the first error message, - * and read the comments preceding that line to see what to change. - * - * Almost all of the edits you may need to make to this program consist of - * changing a line that reads "#define SOME_SYMBOL" to "#undef SOME_SYMBOL", - * or vice versa. This is called defining or undefining that symbol. - */ - - -/* First we must see if your system has the include files we need. - * We start out with the assumption that your system has all the ANSI-standard - * include files. If you get any error trying to include one of these files, - * undefine the corresponding HAVE_xxx symbol. - */ - -#define HAVE_STDDEF_H /* replace 'define' by 'undef' if error here */ -#ifdef HAVE_STDDEF_H /* next line will be skipped if you undef... */ -#include -#endif - -#define HAVE_STDLIB_H /* same thing for stdlib.h */ -#ifdef HAVE_STDLIB_H -#include -#endif - -#include /* If you ain't got this, you ain't got C. */ - -/* We have to see if your string functions are defined by - * strings.h (old BSD convention) or string.h (everybody else). - * We try the non-BSD convention first; define NEED_BSD_STRINGS - * if the compiler says it can't find string.h. - */ - -#undef NEED_BSD_STRINGS - -#ifdef NEED_BSD_STRINGS -#include -#else -#include -#endif - -/* On some systems (especially older Unix machines), type size_t is - * defined only in the include file . If you get a failure - * on the size_t test below, try defining NEED_SYS_TYPES_H. - */ - -#undef NEED_SYS_TYPES_H /* start by assuming we don't need it */ -#ifdef NEED_SYS_TYPES_H -#include -#endif - - -/* Usually type size_t is defined in one of the include files we've included - * above. If not, you'll get an error on the "typedef size_t my_size_t;" line. - * In that case, first try defining NEED_SYS_TYPES_H just above. - * If that doesn't work, you'll have to search through your system library - * to figure out which include file defines "size_t". Look for a line that - * says "typedef something-or-other size_t;". Then, change the line below - * that says "#include " to instead include the file - * you found size_t in, and define NEED_SPECIAL_INCLUDE. If you can't find - * type size_t anywhere, try replacing "#include " with - * "typedef unsigned int size_t;". - */ - -#undef NEED_SPECIAL_INCLUDE /* assume we DON'T need it, for starters */ - -#ifdef NEED_SPECIAL_INCLUDE -#include -#endif - -typedef size_t my_size_t; /* The payoff: do we have size_t now? */ - - -/* The next question is whether your compiler supports ANSI-style function - * prototypes. You need to know this in order to choose between using - * makefile.ansi and using makefile.unix. - * The #define line below is set to assume you have ANSI function prototypes. - * If you get an error in this group of lines, undefine HAVE_PROTOTYPES. - */ - -#define HAVE_PROTOTYPES - -#ifdef HAVE_PROTOTYPES -int testfunction (int arg1, int * arg2); /* check prototypes */ - -struct methods_struct { /* check method-pointer declarations */ - int (*error_exit) (char *msgtext); - int (*trace_message) (char *msgtext); - int (*another_method) (void); -}; - -int testfunction (int arg1, int * arg2) /* check definitions */ -{ - return arg2[arg1]; -} - -int test2function (void) /* check void arg list */ -{ - return 0; -} -#endif - - -/* Now we want to find out if your compiler knows what "unsigned char" means. - * If you get an error on the "unsigned char un_char;" line, - * then undefine HAVE_UNSIGNED_CHAR. - */ - -#define HAVE_UNSIGNED_CHAR - -#ifdef HAVE_UNSIGNED_CHAR -unsigned char un_char; -#endif - - -/* Now we want to find out if your compiler knows what "unsigned short" means. - * If you get an error on the "unsigned short un_short;" line, - * then undefine HAVE_UNSIGNED_SHORT. - */ - -#define HAVE_UNSIGNED_SHORT - -#ifdef HAVE_UNSIGNED_SHORT -unsigned short un_short; -#endif - - -/* Now we want to find out if your compiler understands type "void". - * If you get an error anywhere in here, undefine HAVE_VOID. - */ - -#define HAVE_VOID - -#ifdef HAVE_VOID -/* Caution: a C++ compiler will insist on complete prototypes */ -typedef void * void_ptr; /* check void * */ -#ifdef HAVE_PROTOTYPES /* check ptr to function returning void */ -typedef void (*void_func) (int a, int b); -#else -typedef void (*void_func) (); -#endif - -#ifdef HAVE_PROTOTYPES /* check void function result */ -void test3function (void_ptr arg1, void_func arg2) -#else -void test3function (arg1, arg2) - void_ptr arg1; - void_func arg2; -#endif -{ - char * locptr = (char *) arg1; /* check casting to and from void * */ - arg1 = (void *) locptr; - (*arg2) (1, 2); /* check call of fcn returning void */ -} -#endif - - -/* Now we want to find out if your compiler knows what "const" means. - * If you get an error here, undefine HAVE_CONST. - */ - -#define HAVE_CONST - -#ifdef HAVE_CONST -static const int carray[3] = {1, 2, 3}; - -#ifdef HAVE_PROTOTYPES -int test4function (const int arg1) -#else -int test4function (arg1) - const int arg1; -#endif -{ - return carray[arg1]; -} -#endif - - -/* If you get an error or warning about this structure definition, - * define INCOMPLETE_TYPES_BROKEN. - */ - -#undef INCOMPLETE_TYPES_BROKEN - -#ifndef INCOMPLETE_TYPES_BROKEN -typedef struct undefined_structure * undef_struct_ptr; -#endif - - -/* If you get an error about duplicate names, - * define NEED_SHORT_EXTERNAL_NAMES. - */ - -#undef NEED_SHORT_EXTERNAL_NAMES - -#ifndef NEED_SHORT_EXTERNAL_NAMES - -int possibly_duplicate_function () -{ - return 0; -} - -int possibly_dupli_function () -{ - return 1; -} - -#endif - - - -/************************************************************************ - * OK, that's it. You should not have to change anything beyond this - * point in order to compile and execute this program. (You might get - * some warnings, but you can ignore them.) - * When you run the program, it will make a couple more tests that it - * can do automatically, and then it will create jconfig.h and print out - * any additional suggestions it has. - ************************************************************************ - */ - - -#ifdef HAVE_PROTOTYPES -int is_char_signed (int arg) -#else -int is_char_signed (arg) - int arg; -#endif -{ - if (arg == 189) { /* expected result for unsigned char */ - return 0; /* type char is unsigned */ - } - else if (arg != -67) { /* expected result for signed char */ - printf("Hmm, it seems 'char' is not eight bits wide on your machine.\n"); - printf("I fear the JPEG software will not work at all.\n\n"); - } - return 1; /* assume char is signed otherwise */ -} - - -#ifdef HAVE_PROTOTYPES -int is_shifting_signed (long arg) -#else -int is_shifting_signed (arg) - long arg; -#endif -/* See whether right-shift on a long is signed or not. */ -{ - long res = arg >> 4; - - if (res == -0x7F7E80CL) { /* expected result for signed shift */ - return 1; /* right shift is signed */ - } - /* see if unsigned-shift hack will fix it. */ - /* we can't just test exact value since it depends on width of long... */ - res |= (~0L) << (32-4); - if (res == -0x7F7E80CL) { /* expected result now? */ - return 0; /* right shift is unsigned */ - } - printf("Right shift isn't acting as I expect it to.\n"); - printf("I fear the JPEG software will not work at all.\n\n"); - return 0; /* try it with unsigned anyway */ -} - - -#ifdef HAVE_PROTOTYPES -int main (int argc, char ** argv) -#else -int main (argc, argv) - int argc; - char ** argv; -#endif -{ - char signed_char_check = (char) (-67); - FILE *outfile; - - /* Attempt to write jconfig.h */ - if ((outfile = fopen("jconfig.h", "w")) == NULL) { - printf("Failed to write jconfig.h\n"); - return 1; - } - - /* Write out all the info */ - fprintf(outfile, "/* jconfig.h --- generated by ckconfig.c */\n"); - fprintf(outfile, "/* see jconfig.txt for explanations */\n\n"); -#ifdef HAVE_PROTOTYPES - fprintf(outfile, "#define HAVE_PROTOTYPES\n"); -#else - fprintf(outfile, "#undef HAVE_PROTOTYPES\n"); -#endif -#ifdef HAVE_UNSIGNED_CHAR - fprintf(outfile, "#define HAVE_UNSIGNED_CHAR\n"); -#else - fprintf(outfile, "#undef HAVE_UNSIGNED_CHAR\n"); -#endif -#ifdef HAVE_UNSIGNED_SHORT - fprintf(outfile, "#define HAVE_UNSIGNED_SHORT\n"); -#else - fprintf(outfile, "#undef HAVE_UNSIGNED_SHORT\n"); -#endif -#ifdef HAVE_VOID - fprintf(outfile, "/* #define void char */\n"); -#else - fprintf(outfile, "#define void char\n"); -#endif -#ifdef HAVE_CONST - fprintf(outfile, "/* #define const */\n"); -#else - fprintf(outfile, "#define const\n"); -#endif - if (is_char_signed((int) signed_char_check)) - fprintf(outfile, "#undef CHAR_IS_UNSIGNED\n"); - else - fprintf(outfile, "#define CHAR_IS_UNSIGNED\n"); -#ifdef HAVE_STDDEF_H - fprintf(outfile, "#define HAVE_STDDEF_H\n"); -#else - fprintf(outfile, "#undef HAVE_STDDEF_H\n"); -#endif -#ifdef HAVE_STDLIB_H - fprintf(outfile, "#define HAVE_STDLIB_H\n"); -#else - fprintf(outfile, "#undef HAVE_STDLIB_H\n"); -#endif -#ifdef NEED_BSD_STRINGS - fprintf(outfile, "#define NEED_BSD_STRINGS\n"); -#else - fprintf(outfile, "#undef NEED_BSD_STRINGS\n"); -#endif -#ifdef NEED_SYS_TYPES_H - fprintf(outfile, "#define NEED_SYS_TYPES_H\n"); -#else - fprintf(outfile, "#undef NEED_SYS_TYPES_H\n"); -#endif - fprintf(outfile, "#undef NEED_FAR_POINTERS\n"); -#ifdef NEED_SHORT_EXTERNAL_NAMES - fprintf(outfile, "#define NEED_SHORT_EXTERNAL_NAMES\n"); -#else - fprintf(outfile, "#undef NEED_SHORT_EXTERNAL_NAMES\n"); -#endif -#ifdef INCOMPLETE_TYPES_BROKEN - fprintf(outfile, "#define INCOMPLETE_TYPES_BROKEN\n"); -#else - fprintf(outfile, "#undef INCOMPLETE_TYPES_BROKEN\n"); -#endif - fprintf(outfile, "\n#ifdef JPEG_INTERNALS\n\n"); - if (is_shifting_signed(-0x7F7E80B1L)) - fprintf(outfile, "#undef RIGHT_SHIFT_IS_UNSIGNED\n"); - else - fprintf(outfile, "#define RIGHT_SHIFT_IS_UNSIGNED\n"); - fprintf(outfile, "\n#endif /* JPEG_INTERNALS */\n"); - fprintf(outfile, "\n#ifdef JPEG_CJPEG_DJPEG\n\n"); - fprintf(outfile, "#define BMP_SUPPORTED /* BMP image file format */\n"); - fprintf(outfile, "#define GIF_SUPPORTED /* GIF image file format */\n"); - fprintf(outfile, "#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */\n"); - fprintf(outfile, "#undef RLE_SUPPORTED /* Utah RLE image file format */\n"); - fprintf(outfile, "#define TARGA_SUPPORTED /* Targa image file format */\n\n"); - fprintf(outfile, "#undef TWO_FILE_COMMANDLINE /* You may need this on non-Unix systems */\n"); - fprintf(outfile, "#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */\n"); - fprintf(outfile, "#undef DONT_USE_B_MODE\n"); - fprintf(outfile, "/* #define PROGRESS_REPORT */ /* optional */\n"); - fprintf(outfile, "\n#endif /* JPEG_CJPEG_DJPEG */\n"); - - /* Close the jconfig.h file */ - fclose(outfile); - - /* User report */ - printf("Configuration check for Independent JPEG Group's software done.\n"); - printf("\nI have written the jconfig.h file for you.\n\n"); -#ifdef HAVE_PROTOTYPES - printf("You should use makefile.ansi as the starting point for your Makefile.\n"); -#else - printf("You should use makefile.unix as the starting point for your Makefile.\n"); -#endif - -#ifdef NEED_SPECIAL_INCLUDE - printf("\nYou'll need to change jconfig.h to include the system include file\n"); - printf("that you found type size_t in, or add a direct definition of type\n"); - printf("size_t if that's what you used. Just add it to the end.\n"); -#endif - - return 0; -} diff --git a/uppsrc/plugin/jpg/lib/djpeg.c b/uppsrc/plugin/jpg/lib/djpeg.c deleted file mode 100644 index a01b39684..000000000 --- a/uppsrc/plugin/jpg/lib/djpeg.c +++ /dev/null @@ -1,631 +0,0 @@ -/* - * djpeg.c - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2009-2019 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a command-line user interface for the JPEG decompressor. - * It should work on any system with Unix- or MS-DOS-style command lines. - * - * Two different command line styles are permitted, depending on the - * compile-time switch TWO_FILE_COMMANDLINE: - * djpeg [options] inputfile outputfile - * djpeg [options] [inputfile] - * In the second style, output is always to standard output, which you'd - * normally redirect to a file or pipe to some other program. Input is - * either from a named file or from standard input (typically redirected). - * The second style is convenient on Unix but is unhelpful on systems that - * don't support pipes. Also, you MUST use the first style if your system - * doesn't do binary I/O to stdin/stdout. - * To simplify script writing, the "-outfile" switch is provided. The syntax - * djpeg [options] -outfile outputfile inputfile - * works regardless of which command line style is used. - */ - -#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ -#include "jversion.h" /* for version message */ - -#include /* to declare isprint() */ - -#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ -#ifdef __MWERKS__ -#include /* Metrowerks needs this */ -#include /* ... and this */ -#endif -#ifdef THINK_C -#include /* Think declares it here */ -#endif -#endif - - -/* Create the add-on message string table. */ - -#define JMESSAGE(code,string) string , - -static const char * const cdjpeg_message_table[] = { -#include "cderror.h" - NULL -}; - - -/* - * This list defines the known output image formats - * (not all of which need be supported by a given version). - * You can change the default output format by defining DEFAULT_FMT; - * indeed, you had better do so if you undefine PPM_SUPPORTED. - */ - -typedef enum { - FMT_BMP, /* BMP format (Windows flavor) */ - FMT_GIF, /* GIF format (LZW compressed) */ - FMT_GIF0, /* GIF format (uncompressed) */ - FMT_OS2, /* BMP format (OS/2 flavor) */ - FMT_PPM, /* PPM/PGM (PBMPLUS formats) */ - FMT_RLE, /* RLE format */ - FMT_TARGA, /* Targa format */ - FMT_TIFF /* TIFF format */ -} IMAGE_FORMATS; - -#ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */ -#define DEFAULT_FMT FMT_PPM -#endif - -static IMAGE_FORMATS requested_fmt; - - -/* - * Argument-parsing code. - * The switch parser is designed to be useful with DOS-style command line - * syntax, ie, intermixed switches and file names, where only the switches - * to the left of a given file name affect processing of that file. - * The main program in this file doesn't actually use this capability... - */ - - -static const char * progname; /* program name for error messages */ -static char * outfilename; /* for -outfile switch */ - - -LOCAL(void) -usage (void) -/* complain about bad command line */ -{ - fprintf(stderr, "usage: %s [switches] ", progname); -#ifdef TWO_FILE_COMMANDLINE - fprintf(stderr, "inputfile outputfile\n"); -#else - fprintf(stderr, "[inputfile]\n"); -#endif - - fprintf(stderr, "Switches (names may be abbreviated):\n"); - fprintf(stderr, " -colors N Reduce image to no more than N colors\n"); - fprintf(stderr, " -fast Fast, low-quality processing\n"); - fprintf(stderr, " -grayscale Force grayscale output\n"); - fprintf(stderr, " -rgb Force RGB output\n"); -#ifdef IDCT_SCALING_SUPPORTED - fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\n"); -#endif -#ifdef BMP_SUPPORTED - fprintf(stderr, " -bmp Select BMP output format (Windows style)%s\n", - (DEFAULT_FMT == FMT_BMP ? " (default)" : "")); -#endif -#ifdef GIF_SUPPORTED - fprintf(stderr, " -gif Select GIF output format (LZW compressed)%s\n", - (DEFAULT_FMT == FMT_GIF ? " (default)" : "")); - fprintf(stderr, " -gif0 Select GIF output format (uncompressed)%s\n", - (DEFAULT_FMT == FMT_GIF0 ? " (default)" : "")); -#endif -#ifdef BMP_SUPPORTED - fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n", - (DEFAULT_FMT == FMT_OS2 ? " (default)" : "")); -#endif -#ifdef PPM_SUPPORTED - fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n", - (DEFAULT_FMT == FMT_PPM ? " (default)" : "")); -#endif -#ifdef RLE_SUPPORTED - fprintf(stderr, " -rle Select Utah RLE output format%s\n", - (DEFAULT_FMT == FMT_RLE ? " (default)" : "")); -#endif -#ifdef TARGA_SUPPORTED - fprintf(stderr, " -targa Select Targa output format%s\n", - (DEFAULT_FMT == FMT_TARGA ? " (default)" : "")); -#endif - fprintf(stderr, "Switches for advanced users:\n"); -#ifdef DCT_ISLOW_SUPPORTED - fprintf(stderr, " -dct int Use integer DCT method%s\n", - (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); -#endif -#ifdef DCT_IFAST_SUPPORTED - fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n", - (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : "")); -#endif -#ifdef DCT_FLOAT_SUPPORTED - fprintf(stderr, " -dct float Use floating-point DCT method%s\n", - (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); -#endif - fprintf(stderr, " -dither fs Use F-S dithering (default)\n"); - fprintf(stderr, " -dither none Don't use dithering in quantization\n"); - fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)\n"); -#ifdef QUANT_2PASS_SUPPORTED - fprintf(stderr, " -map FILE Map to colors used in named image file\n"); -#endif - fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n"); -#ifdef QUANT_1PASS_SUPPORTED - fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\n"); -#endif - fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); - fprintf(stderr, " -outfile name Specify name for output file\n"); - fprintf(stderr, " -verbose or -debug Emit debug output\n"); - exit(EXIT_FAILURE); -} - - -LOCAL(int) -parse_switches (j_decompress_ptr cinfo, int argc, char **argv, - int last_file_arg_seen, boolean for_real) -/* Parse optional switches. - * Returns argv[] index of first file-name argument (== argc if none). - * Any file names with indexes <= last_file_arg_seen are ignored; - * they have presumably been processed in a previous iteration. - * (Pass 0 for last_file_arg_seen on the first or only iteration.) - * for_real is FALSE on the first (dummy) pass; we may skip any expensive - * processing. - */ -{ - int argn; - char * arg; - - /* Set up default JPEG parameters. */ - requested_fmt = DEFAULT_FMT; /* set default output file format */ - outfilename = NULL; - cinfo->err->trace_level = 0; - - /* Scan command line options, adjust parameters */ - - for (argn = 1; argn < argc; argn++) { - arg = argv[argn]; - if (*arg != '-') { - /* Not a switch, must be a file name argument */ - if (argn <= last_file_arg_seen) { - outfilename = NULL; /* -outfile applies to just one input file */ - continue; /* ignore this name if previously processed */ - } - break; /* else done parsing switches */ - } - arg++; /* advance past switch marker character */ - - if (keymatch(arg, "bmp", 1)) { - /* BMP output format (Windows flavor). */ - requested_fmt = FMT_BMP; - - } else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) || - keymatch(arg, "quantize", 1) || keymatch(arg, "quantise", 1)) { - /* Do color quantization. */ - int val; - - if (++argn >= argc) /* advance to next argument */ - usage(); - if (sscanf(argv[argn], "%d", &val) != 1) - usage(); - cinfo->desired_number_of_colors = val; - cinfo->quantize_colors = TRUE; - - } else if (keymatch(arg, "dct", 2)) { - /* Select IDCT algorithm. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - if (keymatch(argv[argn], "int", 1)) { - cinfo->dct_method = JDCT_ISLOW; - } else if (keymatch(argv[argn], "fast", 2)) { - cinfo->dct_method = JDCT_IFAST; - } else if (keymatch(argv[argn], "float", 2)) { - cinfo->dct_method = JDCT_FLOAT; - } else - usage(); - - } else if (keymatch(arg, "dither", 2)) { - /* Select dithering algorithm. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - if (keymatch(argv[argn], "fs", 2)) { - cinfo->dither_mode = JDITHER_FS; - } else if (keymatch(argv[argn], "none", 2)) { - cinfo->dither_mode = JDITHER_NONE; - } else if (keymatch(argv[argn], "ordered", 2)) { - cinfo->dither_mode = JDITHER_ORDERED; - } else - usage(); - - } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { - /* Enable debug printouts. */ - /* On first -d, print version identification */ - static boolean printed_version = FALSE; - - if (! printed_version) { - fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n", - JVERSION, JCOPYRIGHT); - printed_version = TRUE; - } - cinfo->err->trace_level++; - - } else if (keymatch(arg, "fast", 1)) { - /* Select recommended processing options for quick-and-dirty output. */ - cinfo->two_pass_quantize = FALSE; - cinfo->dither_mode = JDITHER_ORDERED; - if (! cinfo->quantize_colors) /* don't override an earlier -colors */ - cinfo->desired_number_of_colors = 216; - cinfo->dct_method = JDCT_FASTEST; - cinfo->do_fancy_upsampling = FALSE; - - } else if (keymatch(arg, "gif", 1)) { - /* GIF output format (LZW compressed). */ - requested_fmt = FMT_GIF; - - } else if (keymatch(arg, "gif0", 4)) { - /* GIF output format (uncompressed). */ - requested_fmt = FMT_GIF0; - - } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { - /* Force monochrome output. */ - cinfo->out_color_space = JCS_GRAYSCALE; - - } else if (keymatch(arg, "rgb", 3)) { - /* Force RGB output. */ - cinfo->out_color_space = JCS_RGB; - - } else if (keymatch(arg, "map", 3)) { - /* Quantize to a color map taken from an input file. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - if (for_real) { /* too expensive to do twice! */ -#ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */ - FILE * mapfile; - - if ((mapfile = fopen(argv[argn], READ_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); - exit(EXIT_FAILURE); - } - read_color_map(cinfo, mapfile); - fclose(mapfile); - cinfo->quantize_colors = TRUE; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } - - } else if (keymatch(arg, "maxmemory", 3)) { - /* Maximum memory in Kb (or Mb with 'm'). */ - long lval; - char ch = 'x'; - - if (++argn >= argc) /* advance to next argument */ - usage(); - if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) - usage(); - if (ch == 'm' || ch == 'M') - lval *= 1000L; - cinfo->mem->max_memory_to_use = lval * 1000L; - - } else if (keymatch(arg, "nosmooth", 3)) { - /* Suppress fancy upsampling. */ - cinfo->do_fancy_upsampling = FALSE; - - } else if (keymatch(arg, "onepass", 3)) { - /* Use fast one-pass quantization. */ - cinfo->two_pass_quantize = FALSE; - - } else if (keymatch(arg, "os2", 3)) { - /* BMP output format (OS/2 flavor). */ - requested_fmt = FMT_OS2; - - } else if (keymatch(arg, "outfile", 4)) { - /* Set output file name. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - outfilename = argv[argn]; /* save it away for later use */ - - } else if (keymatch(arg, "pnm", 1) || keymatch(arg, "ppm", 1)) { - /* PPM/PGM output format. */ - requested_fmt = FMT_PPM; - - } else if (keymatch(arg, "rle", 1)) { - /* RLE output format. */ - requested_fmt = FMT_RLE; - - } else if (keymatch(arg, "scale", 1)) { - /* Scale the output image by a fraction M/N. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - if (sscanf(argv[argn], "%u/%u", - &cinfo->scale_num, &cinfo->scale_denom) < 1) - usage(); - - } else if (keymatch(arg, "targa", 1)) { - /* Targa output format. */ - requested_fmt = FMT_TARGA; - - } else { - usage(); /* bogus switch */ - } - } - - return argn; /* return index of next arg (file name) */ -} - - -/* - * Marker processor for COM and interesting APPn markers. - * This replaces the library's built-in processor, which just skips the marker. - * We want to print out the marker as text, to the extent possible. - * Note this code relies on a non-suspending data source. - */ - -LOCAL(unsigned int) -jpeg_getc (j_decompress_ptr cinfo) -/* Read next byte */ -{ - struct jpeg_source_mgr * datasrc = cinfo->src; - - if (datasrc->bytes_in_buffer == 0) { - if (! (*datasrc->fill_input_buffer) (cinfo)) - ERREXIT(cinfo, JERR_CANT_SUSPEND); - } - datasrc->bytes_in_buffer--; - return GETJOCTET(*datasrc->next_input_byte++); -} - - -METHODDEF(boolean) -print_text_marker (j_decompress_ptr cinfo) -{ - boolean traceit = (cinfo->err->trace_level >= 1); - INT32 length; - unsigned int ch; - unsigned int lastch = 0; - - length = jpeg_getc(cinfo) << 8; - length += jpeg_getc(cinfo); - length -= 2; /* discount the length word itself */ - - if (traceit) { - if (cinfo->unread_marker == JPEG_COM) - fprintf(stderr, "Comment, length %ld:\n", (long) length); - else /* assume it is an APPn otherwise */ - fprintf(stderr, "APP%d, length %ld:\n", - cinfo->unread_marker - JPEG_APP0, (long) length); - } - - while (--length >= 0) { - ch = jpeg_getc(cinfo); - if (traceit) { - /* Emit the character in a readable form. - * Nonprintables are converted to \nnn form, - * while \ is converted to \\. - * Newlines in CR, CR/LF, or LF form will be printed as one newline. - */ - if (ch == '\r') { - fprintf(stderr, "\n"); - } else if (ch == '\n') { - if (lastch != '\r') - fprintf(stderr, "\n"); - } else if (ch == '\\') { - fprintf(stderr, "\\\\"); - } else if (isprint(ch)) { - putc(ch, stderr); - } else { - fprintf(stderr, "\\%03o", ch); - } - lastch = ch; - } - } - - if (traceit) - fprintf(stderr, "\n"); - - return TRUE; -} - - -/* - * The main program. - */ - -int -main (int argc, char **argv) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; -#ifdef PROGRESS_REPORT - struct cdjpeg_progress_mgr progress; -#endif - int file_index; - djpeg_dest_ptr dest_mgr = NULL; - FILE * input_file; - FILE * output_file; - JDIMENSION num_scanlines; - - /* On Mac, fetch a command line. */ -#ifdef USE_CCOMMAND - argc = ccommand(&argv); -#endif - - progname = argv[0]; - if (progname == NULL || progname[0] == 0) - progname = "djpeg"; /* in case C library doesn't provide it */ - - /* Initialize the JPEG decompression object with default error handling. */ - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - /* Add some application-specific error messages (from cderror.h) */ - jerr.addon_message_table = cdjpeg_message_table; - jerr.first_addon_message = JMSG_FIRSTADDONCODE; - jerr.last_addon_message = JMSG_LASTADDONCODE; - - /* Insert custom marker processor for COM and APP12. - * APP12 is used by some digital camera makers for textual info, - * so we provide the ability to display it as text. - * If you like, additional APPn marker types can be selected for display, - * but don't try to override APP0 or APP14 this way (see libjpeg.txt). - */ - jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker); - jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker); - - /* Now safe to enable signal catcher. */ -#ifdef NEED_SIGNAL_CATCHER - enable_signal_catcher((j_common_ptr) &cinfo); -#endif - - /* Scan command line to find file names. */ - /* It is convenient to use just one switch-parsing routine, but the switch - * values read here are ignored; we will rescan the switches after opening - * the input file. - * (Exception: tracing level set here controls verbosity for COM markers - * found during jpeg_read_header...) - */ - - file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); - -#ifdef TWO_FILE_COMMANDLINE - /* Must have either -outfile switch or explicit output file name */ - if (outfilename == NULL) { - if (file_index != argc-2) { - fprintf(stderr, "%s: must name one input and one output file\n", - progname); - usage(); - } - outfilename = argv[file_index+1]; - } else { - if (file_index != argc-1) { - fprintf(stderr, "%s: must name one input and one output file\n", - progname); - usage(); - } - } -#else - /* Unix style: expect zero or one file name */ - if (file_index < argc-1) { - fprintf(stderr, "%s: only one input file\n", progname); - usage(); - } -#endif /* TWO_FILE_COMMANDLINE */ - - /* Open the input file. */ - if (file_index < argc) { - if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); - exit(EXIT_FAILURE); - } - } else { - /* default input file is stdin */ - input_file = read_stdin(); - } - - /* Open the output file. */ - if (outfilename != NULL) { - if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s\n", progname, outfilename); - exit(EXIT_FAILURE); - } - } else { - /* default output file is stdout */ - output_file = write_stdout(); - } - -#ifdef PROGRESS_REPORT - start_progress_monitor((j_common_ptr) &cinfo, &progress); -#endif - - /* Specify data source for decompression */ - jpeg_stdio_src(&cinfo, input_file); - - /* Read file header, set default decompression parameters */ - (void) jpeg_read_header(&cinfo, TRUE); - - /* Adjust default decompression parameters by re-parsing the options */ - file_index = parse_switches(&cinfo, argc, argv, 0, TRUE); - - /* Initialize the output module now to let it override any crucial - * option settings (for instance, GIF wants to force color quantization). - */ - switch (requested_fmt) { -#ifdef BMP_SUPPORTED - case FMT_BMP: - dest_mgr = jinit_write_bmp(&cinfo, FALSE); - break; - case FMT_OS2: - dest_mgr = jinit_write_bmp(&cinfo, TRUE); - break; -#endif -#ifdef GIF_SUPPORTED - case FMT_GIF: - dest_mgr = jinit_write_gif(&cinfo, TRUE); - break; - case FMT_GIF0: - dest_mgr = jinit_write_gif(&cinfo, FALSE); - break; -#endif -#ifdef PPM_SUPPORTED - case FMT_PPM: - dest_mgr = jinit_write_ppm(&cinfo); - break; -#endif -#ifdef RLE_SUPPORTED - case FMT_RLE: - dest_mgr = jinit_write_rle(&cinfo); - break; -#endif -#ifdef TARGA_SUPPORTED - case FMT_TARGA: - dest_mgr = jinit_write_targa(&cinfo); - break; -#endif - default: - ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT); - } - dest_mgr->output_file = output_file; - - /* Start decompressor */ - (void) jpeg_start_decompress(&cinfo); - - /* Write output file header */ - (*dest_mgr->start_output) (&cinfo, dest_mgr); - - /* Process data */ - while (cinfo.output_scanline < cinfo.output_height) { - num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, - dest_mgr->buffer_height); - (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); - } - -#ifdef PROGRESS_REPORT - /* Hack: count final pass as done in case finish_output does an extra pass. - * The library won't have updated completed_passes. - */ - progress.pub.completed_passes = progress.pub.total_passes; -#endif - - /* Finish decompression and release memory. - * I must do it in this order because output module has allocated memory - * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory. - */ - (*dest_mgr->finish_output) (&cinfo, dest_mgr); - (void) jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - - /* Close files, if we opened them */ - if (input_file != stdin) - fclose(input_file); - if (output_file != stdout) - fclose(output_file); - -#ifdef PROGRESS_REPORT - end_progress_monitor((j_common_ptr) &cinfo); -#endif - - /* All done. */ - exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); - return 0; /* suppress no-return-value warnings */ -} diff --git a/uppsrc/plugin/jpg/lib/djpegalt.c b/uppsrc/plugin/jpg/lib/djpegalt.c index da809ae4a..969c58b49 100644 --- a/uppsrc/plugin/jpg/lib/djpegalt.c +++ b/uppsrc/plugin/jpg/lib/djpegalt.c @@ -2,7 +2,7 @@ * alternate djpeg.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2009-2020 by Guido Vollbeding. + * Modified 2009-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -74,7 +74,7 @@ unused_dos_memory (void) #endif /* MSDOS */ -#ifdef ATARI /* For Atari ST/STE/TT, Pure C or Turbo C */ +#ifdef ATARI /* For Atari ST/Mega/STE/TT/Falcon, Pure C or Turbo C */ #include diff --git a/uppsrc/plugin/jpg/lib/example.c b/uppsrc/plugin/jpg/lib/example.c deleted file mode 100644 index 1d6f6cc30..000000000 --- a/uppsrc/plugin/jpg/lib/example.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * example.c - * - * This file illustrates how to use the IJG code as a subroutine library - * to read or write JPEG image files. You should look at this code in - * conjunction with the documentation file libjpeg.txt. - * - * This code will not do anything useful as-is, but it may be helpful as a - * skeleton for constructing routines that call the JPEG library. - * - * We present these routines in the same coding style used in the JPEG code - * (ANSI function definitions, etc); but you are of course free to code your - * routines in a different style if you prefer. - */ - -#include - -/* - * Include file for users of JPEG library. - * You will need to have included system headers that define at least - * the typedefs FILE and size_t before you can include jpeglib.h. - * (stdio.h is sufficient on ANSI-conforming systems.) - * You may also wish to include "jerror.h". - */ - -#include "jpeglib.h" - -/* - * is used for the optional error recovery mechanism shown in - * the second part of the example. - */ - -#include - - - -/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/ - -/* This half of the example shows how to feed data into the JPEG compressor. - * We present a minimal version that does not worry about refinements such - * as error recovery (the JPEG code will just exit() if it gets an error). - */ - - -/* - * IMAGE DATA FORMATS: - * - * The standard input image format is a rectangular array of pixels, with - * each pixel having the same number of "component" values (color channels). - * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars). - * If you are working with color data, then the color values for each pixel - * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit - * RGB color. - * - * For this example, we'll assume that this data structure matches the way - * our application has stored the image in memory, so we can just pass a - * pointer to our image buffer. In particular, let's say that the image is - * RGB color and is described by: - */ - -extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */ -extern int image_height; /* Number of rows in image */ -extern int image_width; /* Number of columns in image */ - - -/* - * Sample routine for JPEG compression. We assume that the target file name - * and a compression quality factor are passed in. - */ - -GLOBAL(void) -write_JPEG_file (char * filename, int quality) -{ - /* This struct contains the JPEG compression parameters and pointers to - * working space (which is allocated as needed by the JPEG library). - * It is possible to have several such structures, representing multiple - * compression/decompression processes, in existence at once. We refer - * to any one struct (and its associated working data) as a "JPEG object". - */ - struct jpeg_compress_struct cinfo; - /* This struct represents a JPEG error handler. It is declared separately - * because applications often want to supply a specialized error handler - * (see the second half of this file for an example). But here we just - * take the easy way out and use the standard error handler, which will - * print a message on stderr and call exit() if compression fails. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - struct jpeg_error_mgr jerr; - /* More stuff */ - FILE * outfile; /* target file */ - JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ - int row_stride; /* physical row width in image buffer */ - - /* Step 1: allocate and initialize JPEG compression object */ - - /* We have to set up the error handler first, in case the initialization - * step fails. (Unlikely, but it could happen if you are out of memory.) - * This routine fills in the contents of struct jerr, and returns jerr's - * address which we place into the link field in cinfo. - */ - cinfo.err = jpeg_std_error(&jerr); - /* Now we can initialize the JPEG compression object. */ - jpeg_create_compress(&cinfo); - - /* Step 2: specify data destination (eg, a file) */ - /* Note: steps 2 and 3 can be done in either order. */ - - /* Here we use the library-supplied code to send compressed data to a - * stdio stream. You can also write your own code to do something else. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to write binary files. - */ - if ((outfile = fopen(filename, "wb")) == NULL) { - fprintf(stderr, "can't open %s\n", filename); - exit(1); - } - jpeg_stdio_dest(&cinfo, outfile); - - /* Step 3: set parameters for compression */ - - /* First we supply a description of the input image. - * Four fields of the cinfo struct must be filled in: - */ - cinfo.image_width = image_width; /* image width and height, in pixels */ - cinfo.image_height = image_height; - cinfo.input_components = 3; /* # of color components per pixel */ - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ - /* Now use the library's routine to set default compression parameters. - * (You must set at least cinfo.in_color_space before calling this, - * since the defaults depend on the source color space.) - */ - jpeg_set_defaults(&cinfo); - /* Now you can set any non-default parameters you wish to. - * Here we just illustrate the use of quality (quantization table) scaling: - */ - jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); - - /* Step 4: Start compressor */ - - /* TRUE ensures that we will write a complete interchange-JPEG file. - * Pass TRUE unless you are very sure of what you're doing. - */ - jpeg_start_compress(&cinfo, TRUE); - - /* Step 5: while (scan lines remain to be written) */ - /* jpeg_write_scanlines(...); */ - - /* Here we use the library's state variable cinfo.next_scanline as the - * loop counter, so that we don't have to keep track ourselves. - * To keep things simple, we pass one scanline per call; you can pass - * more if you wish, though. - */ - row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */ - - while (cinfo.next_scanline < cinfo.image_height) { - /* jpeg_write_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could pass - * more than one scanline at a time if that's more convenient. - */ - row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; - (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - - /* Step 6: Finish compression */ - - jpeg_finish_compress(&cinfo); - /* After finish_compress, we can close the output file. */ - fclose(outfile); - - /* Step 7: release JPEG compression object */ - - /* This is an important step since it will release a good deal of memory. */ - jpeg_destroy_compress(&cinfo); - - /* And we're done! */ -} - - -/* - * SOME FINE POINTS: - * - * In the above loop, we ignored the return value of jpeg_write_scanlines, - * which is the number of scanlines actually written. We could get away - * with this because we were only relying on the value of cinfo.next_scanline, - * which will be incremented correctly. If you maintain additional loop - * variables then you should be careful to increment them properly. - * Actually, for output to a stdio stream you needn't worry, because - * then jpeg_write_scanlines will write all the lines passed (or else exit - * with a fatal error). Partial writes can only occur if you use a data - * destination module that can demand suspension of the compressor. - * (If you don't know what that's for, you don't need it.) - * - * If the compressor requires full-image buffers (for entropy-coding - * optimization or a multi-scan JPEG file), it will create temporary - * files for anything that doesn't fit within the maximum-memory setting. - * (Note that temp files are NOT needed if you use the default parameters.) - * On some systems you may need to set up a signal handler to ensure that - * temporary files are deleted if the program is interrupted. See libjpeg.txt. - * - * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG - * files to be compatible with everyone else's. If you cannot readily read - * your data in that order, you'll need an intermediate array to hold the - * image. See rdtarga.c or rdbmp.c for examples of handling bottom-to-top - * source data using the JPEG code's internal virtual-array mechanisms. - */ - - - -/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/ - -/* This half of the example shows how to read data from the JPEG decompressor. - * It's a bit more refined than the above, in that we show: - * (a) how to modify the JPEG library's standard error-reporting behavior; - * (b) how to allocate workspace using the library's memory manager. - * - * Just to make this example a little different from the first one, we'll - * assume that we do not intend to put the whole image into an in-memory - * buffer, but to send it line-by-line someplace else. We need a one- - * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG - * memory manager allocate it for us. This approach is actually quite useful - * because we don't need to remember to deallocate the buffer separately: it - * will go away automatically when the JPEG object is cleaned up. - */ - - -/* - * ERROR HANDLING: - * - * The JPEG library's standard error handler (jerror.c) is divided into - * several "methods" which you can override individually. This lets you - * adjust the behavior without duplicating a lot of code, which you might - * have to update with each future release. - * - * Our example here shows how to override the "error_exit" method so that - * control is returned to the library's caller when a fatal error occurs, - * rather than calling exit() as the standard error_exit method does. - * - * We use C's setjmp/longjmp facility to return control. This means that the - * routine which calls the JPEG library must first execute a setjmp() call to - * establish the return point. We want the replacement error_exit to do a - * longjmp(). But we need to make the setjmp buffer accessible to the - * error_exit routine. To do this, we make a private extension of the - * standard JPEG error handler object. (If we were using C++, we'd say we - * were making a subclass of the regular error handler.) - * - * Here's the extended error handler struct: - */ - -struct my_error_mgr { - struct jpeg_error_mgr pub; /* "public" fields */ - - jmp_buf setjmp_buffer; /* for return to caller */ -}; - -typedef struct my_error_mgr * my_error_ptr; - -/* - * Here's the routine that will replace the standard error_exit method: - */ - -METHODDEF(void) -my_error_exit (j_common_ptr cinfo) -{ - /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ - my_error_ptr myerr = (my_error_ptr) cinfo->err; - - /* Always display the message. */ - /* We could postpone this until after returning, if we chose. */ - (*cinfo->err->output_message) (cinfo); - - /* Return control to the setjmp point */ - longjmp(myerr->setjmp_buffer, 1); -} - - -/* - * Sample routine for JPEG decompression. We assume that the source file name - * is passed in. We want to return 1 on success, 0 on error. - */ - - -GLOBAL(int) -read_JPEG_file (char * filename) -{ - /* This struct contains the JPEG decompression parameters and pointers to - * working space (which is allocated as needed by the JPEG library). - */ - struct jpeg_decompress_struct cinfo; - /* We use our private extension JPEG error handler. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - struct my_error_mgr jerr; - /* More stuff */ - FILE * infile; /* source file */ - JSAMPARRAY buffer; /* Output row buffer */ - int row_stride; /* physical row width in output buffer */ - - /* In this example we want to open the input file before doing anything else, - * so that the setjmp() error recovery below can assume the file is open. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to read binary files. - */ - - if ((infile = fopen(filename, "rb")) == NULL) { - fprintf(stderr, "can't open %s\n", filename); - return 0; - } - - /* Step 1: allocate and initialize JPEG decompression object */ - - /* We set up the normal JPEG error routines, then override error_exit. */ - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = my_error_exit; - /* Establish the setjmp return context for my_error_exit to use. */ - if (setjmp(jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. - * We need to clean up the JPEG object, close the input file, and return. - */ - jpeg_destroy_decompress(&cinfo); - fclose(infile); - return 0; - } - /* Now we can initialize the JPEG decompression object. */ - jpeg_create_decompress(&cinfo); - - /* Step 2: specify data source (eg, a file) */ - - jpeg_stdio_src(&cinfo, infile); - - /* Step 3: read file parameters with jpeg_read_header() */ - - (void) jpeg_read_header(&cinfo, TRUE); - /* We can ignore the return value from jpeg_read_header since - * (a) suspension is not possible with the stdio data source, and - * (b) we passed TRUE to reject a tables-only JPEG file as an error. - * See libjpeg.txt for more info. - */ - - /* Step 4: set parameters for decompression */ - - /* In this example, we don't need to change any of the defaults set by - * jpeg_read_header(), so we do nothing here. - */ - - /* Step 5: Start decompressor */ - - (void) jpeg_start_decompress(&cinfo); - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* We may need to do some setup of our own at this point before reading - * the data. After jpeg_start_decompress() we have the correct scaled - * output image dimensions available, as well as the output colormap - * if we asked for color quantization. - * In this example, we need to make an output work buffer of the right size. - */ - /* JSAMPLEs per row in output buffer */ - row_stride = cinfo.output_width * cinfo.output_components; - /* Make a one-row-high sample array that will go away when done with image */ - buffer = (*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - - /* Step 6: while (scan lines remain to be read) */ - /* jpeg_read_scanlines(...); */ - - /* Here we use the library's state variable cinfo.output_scanline as the - * loop counter, so that we don't have to keep track ourselves. - */ - while (cinfo.output_scanline < cinfo.output_height) { - /* jpeg_read_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could ask for - * more than one scanline at a time if that's more convenient. - */ - (void) jpeg_read_scanlines(&cinfo, buffer, 1); - /* Assume put_scanline_someplace wants a pointer and sample count. */ - put_scanline_someplace(buffer[0], row_stride); - } - - /* Step 7: Finish decompression */ - - (void) jpeg_finish_decompress(&cinfo); - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* Step 8: Release JPEG decompression object */ - - /* This is an important step since it will release a good deal of memory. */ - jpeg_destroy_decompress(&cinfo); - - /* After finish_decompress, we can close the input file. - * Here we postpone it until after no more JPEG errors are possible, - * so as to simplify the setjmp error logic above. (Actually, I don't - * think that jpeg_destroy can do an error exit, but why assume anything...) - */ - fclose(infile); - - /* At this point you may want to check to see whether any corrupt-data - * warnings occurred (test whether jerr.pub.num_warnings is nonzero). - */ - - /* And we're done! */ - return 1; -} - - -/* - * SOME FINE POINTS: - * - * In the above code, we ignored the return value of jpeg_read_scanlines, - * which is the number of scanlines actually read. We could get away with - * this because we asked for only one line at a time and we weren't using - * a suspending data source. See libjpeg.txt for more info. - * - * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress(); - * we should have done it beforehand to ensure that the space would be - * counted against the JPEG max_memory setting. In some systems the above - * code would risk an out-of-memory error. However, in general we don't - * know the output image dimensions before jpeg_start_decompress(), unless we - * call jpeg_calc_output_dimensions(). See libjpeg.txt for more about this. - * - * Scanlines are returned in the same order as they appear in the JPEG file, - * which is standardly top-to-bottom. If you must emit data bottom-to-top, - * you can use one of the virtual arrays provided by the JPEG memory manager - * to invert the data. See wrbmp.c for an example. - * - * As with compression, some operating modes may require temporary files. - * On some systems you may need to set up a signal handler to ensure that - * temporary files are deleted if the program is interrupted. See libjpeg.txt. - */ diff --git a/uppsrc/plugin/jpg/lib/jccoefct.c b/uppsrc/plugin/jpg/lib/jccoefct.c index f779d433f..7b3d98270 100644 --- a/uppsrc/plugin/jpg/lib/jccoefct.c +++ b/uppsrc/plugin/jpg/lib/jccoefct.c @@ -2,7 +2,7 @@ * jccoefct.c * * Copyright (C) 1994-1997, Thomas G. Lane. - * Modified 2003-2020 by Guido Vollbeding. + * Modified 2003-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -41,9 +41,9 @@ typedef struct { int MCU_rows_per_iMCU_row; /* number of such rows needed */ /* For single-pass compression, it's sufficient to buffer just one MCU - * (although this may prove a bit slow in practice). We append a - * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it - * for each MCU constructed and sent. + * (although this may prove a bit slow in practice). + * We append a workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, + * and reuse it for each MCU constructed and sent. * In multi-pass modes, this array points to the current MCU's blocks * within the virtual arrays. */ diff --git a/uppsrc/plugin/jpg/lib/jccolor.c b/uppsrc/plugin/jpg/lib/jccolor.c index c7ca0e4b0..bfbd54d11 100644 --- a/uppsrc/plugin/jpg/lib/jccolor.c +++ b/uppsrc/plugin/jpg/lib/jccolor.c @@ -2,7 +2,7 @@ * jccolor.c * * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2011-2019 by Guido Vollbeding. + * Modified 2011-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -40,10 +40,10 @@ typedef my_color_converter * my_cconvert_ptr; * Note that the derived conversion coefficients given in some of these * documents are imprecise. The general conversion equations are * Y = Kr * R + (1 - Kr - Kb) * G + Kb * B - * Cb = 0.5 * (B - Y) / (1 - Kb) - * Cr = 0.5 * (R - Y) / (1 - Kr) + * Cb = (B - Y) / (1 - Kb) / K + * Cr = (R - Y) / (1 - Kr) / K * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993 - * from the 1953 FCC NTSC primaries and CIE Illuminant C), + * from the 1953 FCC NTSC primaries and CIE Illuminant C), K = 2 for sYCC, * the conversion equations to be implemented are therefore * Y = 0.299 * R + 0.587 * G + 0.114 * B * Cb = -0.168735892 * R - 0.331264108 * G + 0.5 * B + CENTERJSAMPLE @@ -62,8 +62,8 @@ typedef my_color_converter * my_cconvert_ptr; * by precalculating the constants times R,G,B for all possible values. * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); * for 9-bit to 12-bit samples it is still acceptable. It's not very - * reasonable for 16-bit samples, but if you want lossless storage you - * shouldn't be changing colorspace anyway. + * reasonable for 16-bit samples, but if you want lossless storage + * you shouldn't be changing colorspace anyway. * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included * in the tables to save adding them separately in the inner loop. */ @@ -110,16 +110,16 @@ rgb_ycc_start (j_compress_ptr cinfo) for (i = 0; i <= MAXJSAMPLE; i++) { rgb_ycc_tab[i+R_Y_OFF] = FIX(0.299) * i; rgb_ycc_tab[i+G_Y_OFF] = FIX(0.587) * i; - rgb_ycc_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; + rgb_ycc_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; rgb_ycc_tab[i+R_CB_OFF] = (- FIX(0.168735892)) * i; rgb_ycc_tab[i+G_CB_OFF] = (- FIX(0.331264108)) * i; /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. * This ensures that the maximum output will round to MAXJSAMPLE * not MAXJSAMPLE+1, and thus that we don't have to range-limit. */ - rgb_ycc_tab[i+B_CB_OFF] = FIX(0.5) * i + CBCR_OFFSET + ONE_HALF-1; + rgb_ycc_tab[i+B_CB_OFF] = (i << (SCALEBITS-1)) + CBCR_OFFSET + ONE_HALF-1; /* B=>Cb and R=>Cr tables are the same - rgb_ycc_tab[i+R_CR_OFF] = FIX(0.5) * i + CBCR_OFFSET + ONE_HALF-1; + rgb_ycc_tab[i+R_CR_OFF] = (i << (SCALEBITS-1)) + CBCR_OFFSET + ONE_HALF-1; */ rgb_ycc_tab[i+G_CR_OFF] = (- FIX(0.418687589)) * i; rgb_ycc_tab[i+B_CR_OFF] = (- FIX(0.081312411)) * i; @@ -190,8 +190,8 @@ rgb_ycc_convert (j_compress_ptr cinfo, /* * Convert some rows of samples to the JPEG colorspace. - * This version handles RGB->grayscale conversion, which is the same - * as the RGB->Y portion of RGB->YCbCr. + * This version handles RGB->grayscale conversion, + * which is the same as the RGB->Y portion of RGB->YCbCr. * We assume rgb_ycc_start has been called (we only use the Y tables). */ @@ -201,7 +201,7 @@ rgb_gray_convert (j_compress_ptr cinfo, JDIMENSION output_row, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; + register INT32 y; register INT32 * ctab = cconvert->rgb_ycc_tab; register JSAMPROW inptr; register JSAMPROW outptr; @@ -212,14 +212,11 @@ rgb_gray_convert (j_compress_ptr cinfo, inptr = *input_buf++; outptr = output_buf[0][output_row++]; for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr[RGB_RED]); - g = GETJSAMPLE(inptr[RGB_GREEN]); - b = GETJSAMPLE(inptr[RGB_BLUE]); + y = ctab[R_Y_OFF + GETJSAMPLE(inptr[RGB_RED])]; + y += ctab[G_Y_OFF + GETJSAMPLE(inptr[RGB_GREEN])]; + y += ctab[B_Y_OFF + GETJSAMPLE(inptr[RGB_BLUE])]; inptr += RGB_PIXELSIZE; - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + outptr[col] = (JSAMPLE) (y >> SCALEBITS); } } } diff --git a/uppsrc/plugin/jpg/lib/jchuff.c b/uppsrc/plugin/jpg/lib/jchuff.c index bb3aec592..e7318a647 100644 --- a/uppsrc/plugin/jpg/lib/jchuff.c +++ b/uppsrc/plugin/jpg/lib/jchuff.c @@ -2,7 +2,7 @@ * jchuff.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2006-2020 by Guido Vollbeding. + * Modified 2006-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -26,17 +26,11 @@ /* The legal range of a DCT coefficient is - * -1024 .. +1023 for 8-bit data; - * -16384 .. +16383 for 12-bit data. - * Hence the magnitude should always fit in 10 or 14 bits respectively. + * -1024 .. +1023 for 8-bit sample data precision; + * -16384 .. +16383 for 12-bit sample data precision. + * Hence the magnitude should always fit in sample data precision + 2 bits. */ -#if BITS_IN_JSAMPLE == 8 -#define MAX_COEF_BITS 10 -#else -#define MAX_COEF_BITS 14 -#endif - /* Derived data constructed for each Huffman table */ typedef struct { @@ -547,6 +541,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; register int temp, temp2; register int nbits; + int max_coef_bits; int blkn, ci, tbl; ISHIFT_TEMPS @@ -558,6 +553,9 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) if (entropy->restarts_to_go == 0) emit_restart_e(entropy, entropy->next_restart_num); + /* Since we're encoding a difference, the range limit is twice as much. */ + max_coef_bits = cinfo->data_precision + 3; + /* Encode the MCU data blocks */ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { ci = cinfo->MCU_membership[blkn]; @@ -569,12 +567,17 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) temp = IRIGHT_SHIFT((int) (MCU_data[blkn][0][0]), cinfo->Al); /* DC differences are figured on the point-transformed values. */ - temp2 = temp - entropy->saved.last_dc_val[ci]; + if ((temp2 = temp - entropy->saved.last_dc_val[ci]) == 0) { + /* Count/emit the Huffman-coded symbol for the number of bits */ + emit_dc_symbol(entropy, tbl, 0); + + continue; + } + entropy->saved.last_dc_val[ci] = temp; /* Encode the DC coefficient difference per section G.1.2.1 */ - temp = temp2; - if (temp < 0) { + if ((temp = temp2) < 0) { temp = -temp; /* temp is abs value of input */ /* For a negative input, want temp2 = bitwise complement of abs(input) */ /* This code assumes we are on a two's complement machine */ @@ -583,14 +586,10 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) /* Find the number of bits needed for the magnitude of the coefficient */ nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values */ + if (nbits > max_coef_bits) ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count/emit the Huffman-coded symbol for the number of bits */ @@ -598,8 +597,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ - emit_bits_e(entropy, (unsigned int) temp2, nbits); + emit_bits_e(entropy, (unsigned int) temp2, nbits); } cinfo->dest->next_output_byte = entropy->next_output_byte; @@ -633,7 +631,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) register int temp, temp2; register int nbits; register int r, k; - int Se, Al; + int Se, Al, max_coef_bits; entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; @@ -646,6 +644,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) Se = cinfo->Se; Al = cinfo->Al; natural_order = cinfo->natural_order; + max_coef_bits = cinfo->data_precision + 2; /* Encode the MCU data block */ block = MCU_data[0]; @@ -666,18 +665,23 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) */ if (temp < 0) { temp = -temp; /* temp is abs value of input */ - temp >>= Al; /* apply the point transform */ + /* Apply the point transform, and watch out for case */ + /* that nonzero coef is zero after point transform. */ + if ((temp >>= Al) == 0) { + r++; + continue; + } /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ temp2 = ~temp; } else { - temp >>= Al; /* apply the point transform */ + /* Apply the point transform, and watch out for case */ + /* that nonzero coef is zero after point transform. */ + if ((temp >>= Al) == 0) { + r++; + continue; + } temp2 = temp; } - /* Watch out for case that nonzero coef is zero after point transform */ - if (temp == 0) { - r++; - continue; - } /* Emit any pending EOBRUN */ if (entropy->EOBRUN > 0) @@ -689,11 +693,11 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) } /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) + if (nbits > max_coef_bits) ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count/emit Huffman symbol for run length / number of bits */ @@ -916,83 +920,89 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, register int nbits; register int r, k; int Se = state->cinfo->lim_Se; + int max_coef_bits = state->cinfo->data_precision + 3; const int * natural_order = state->cinfo->natural_order; /* Encode the DC coefficient difference per section F.1.2.1 */ - temp = temp2 = block[0] - last_dc_val; + if ((temp = block[0] - last_dc_val) == 0) { + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits_s(state, dctbl->ehufco[0], dctbl->ehufsi[0])) + return FALSE; + } else { + if ((temp2 = temp) < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* For a negative input, want temp2 = bitwise complement of abs(input) */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > max_coef_bits) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) - ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits_s(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) + return FALSE; - /* Emit the Huffman-coded symbol for the number of bits */ - if (! emit_bits_s(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ if (! emit_bits_s(state, (unsigned int) temp2, nbits)) return FALSE; + } /* Encode the AC coefficients per section F.1.2.2 */ r = 0; /* r = run length of zeros */ for (k = 1; k <= Se; k++) { - if ((temp2 = block[natural_order[k]]) == 0) { + if ((temp = block[natural_order[k]]) == 0) { r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - if (! emit_bits_s(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) - return FALSE; - r -= 16; - } - - temp = temp2; - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) - ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); - - /* Emit Huffman symbol for run length / number of bits */ - temp = (r << 4) + nbits; - if (! emit_bits_s(state, actbl->ehufco[temp], actbl->ehufsi[temp])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (! emit_bits_s(state, (unsigned int) temp2, nbits)) - return FALSE; - - r = 0; + continue; } + + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + if (! emit_bits_s(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) + return FALSE; + r -= 16; + } + + if ((temp2 = temp) < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Use ">=" instead of ">" so can use the + * same one larger limit from DC check here. + */ + if (nbits >= max_coef_bits) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit Huffman symbol for run length / number of bits */ + temp = (r << 4) + nbits; + if (! emit_bits_s(state, actbl->ehufco[temp], actbl->ehufsi[temp])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (! emit_bits_s(state, (unsigned int) temp2, nbits)) + return FALSE; + + r = 0; /* reset zero run length */ } /* If the last coef(s) were zero, emit an end-of-block code */ @@ -1122,28 +1132,31 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, register int nbits; register int r, k; int Se = cinfo->lim_Se; + int max_coef_bits = cinfo->data_precision + 3; const int * natural_order = cinfo->natural_order; /* Encode the DC coefficient difference per section F.1.2.1 */ - temp = block[0] - last_dc_val; - if (temp < 0) - temp = -temp; + if ((temp = block[0] - last_dc_val) == 0) { + /* Count the Huffman symbol for the number of bits */ + dc_counts[0]++; + } else { + if (temp < 0) + temp = -temp; /* temp is abs value of input */ - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > max_coef_bits) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count the Huffman symbol for the number of bits */ + dc_counts[nbits]++; } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) - ERREXIT(cinfo, JERR_BAD_DCT_COEF); - - /* Count the Huffman symbol for the number of bits */ - dc_counts[nbits]++; /* Encode the AC coefficients per section F.1.2.2 */ @@ -1152,30 +1165,33 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, for (k = 1; k <= Se; k++) { if ((temp = block[natural_order[k]]) == 0) { r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - ac_counts[0xF0]++; - r -= 16; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - if (temp < 0) - temp = -temp; - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) - ERREXIT(cinfo, JERR_BAD_DCT_COEF); - - /* Count Huffman symbol for run length / number of bits */ - ac_counts[(r << 4) + nbits]++; - - r = 0; + continue; } + + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + ac_counts[0xF0]++; + r -= 16; + } + + if (temp < 0) + temp = -temp; /* temp is abs value of input */ + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Use ">=" instead of ">" so can use the + * same one larger limit from DC check here. + */ + if (nbits >= max_coef_bits) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count Huffman symbol for run length / number of bits */ + ac_counts[(r << 4) + nbits]++; + + r = 0; /* reset zero run length */ } /* If the last coef(s) were zero, emit an end-of-block code */ diff --git a/uppsrc/plugin/jpg/lib/jconfig.h b/uppsrc/plugin/jpg/lib/jconfig.h index 15eaaeb69..cef47bcf5 100644 --- a/uppsrc/plugin/jpg/lib/jconfig.h +++ b/uppsrc/plugin/jpg/lib/jconfig.h @@ -1,6 +1,8 @@ -/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 9x or NT. */ -/* This file also works for Borland C++ 32-bit (bcc32) on Windows 9x or NT. */ -/* see jconfig.txt for explanations */ +/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 9x or NT. + * This file also works for Borland/Embarcadero C++ for Win32 or Win64 + * (CLI: bcc32, bcc32c, bcc32x, bcc64; GUI IDE: C++Builder/RAD Studio). + * See jconfig.txt for explanations. + */ #define HAVE_PROTOTYPES #define HAVE_UNSIGNED_CHAR @@ -29,6 +31,17 @@ #endif #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +/* Define custom RGB color order, prevent jmorecfg.h from redefinition */ +#undef JPEG_HAVE_RGB_CUSTOM +/* Use Windows custom BGR color order defined in jmorecfg.h */ +#undef JPEG_USE_RGB_CUSTOM + +/* Define custom file I/O functions, prevent jinclude.h from redefinition */ +#undef JPEG_HAVE_FILE_IO_CUSTOM +/* Use Delphi custom file I/O functions defined in jinclude.h */ +#undef JPEG_USE_FILE_IO_CUSTOM + + #ifdef JPEG_INTERNALS #undef RIGHT_SHIFT_IS_UNSIGNED @@ -44,7 +57,7 @@ #define TARGA_SUPPORTED /* Targa image file format */ #define TWO_FILE_COMMANDLINE /* optional */ -#define USE_SETMODE /* Microsoft has setmode() */ +#define USE_SETMODE /* Microsoft/Borland/Embarcadero have setmode() */ #undef NEED_SIGNAL_CATCHER #undef DONT_USE_B_MODE #undef PROGRESS_REPORT /* optional */ diff --git a/uppsrc/plugin/jpg/lib/jdatadst.c b/uppsrc/plugin/jpg/lib/jdatadst.c index cf57d4fd4..cd5151f7c 100644 --- a/uppsrc/plugin/jpg/lib/jdatadst.c +++ b/uppsrc/plugin/jpg/lib/jdatadst.c @@ -2,7 +2,7 @@ * jdatadst.c * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2009-2019 by Guido Vollbeding. + * Modified 2009-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -28,17 +28,17 @@ extern void free JPP((void *ptr)); /* Expanded data destination object for stdio output */ +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ + typedef struct { struct jpeg_destination_mgr pub; /* public fields */ FILE * outfile; /* target stream */ - JOCTET * buffer; /* start of buffer */ + JOCTET buffer[OUTPUT_BUF_SIZE]; /* output buffer */ } my_destination_mgr; typedef my_destination_mgr * my_dest_ptr; -#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ - /* Expanded data destination object for memory output */ @@ -65,10 +65,6 @@ init_destination (j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - /* Allocate the output buffer --- it will be released when done with image */ - dest->buffer = (JOCTET *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); - dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; } @@ -187,8 +183,8 @@ term_mem_destination (j_compress_ptr cinfo) /* * Prepare for output to a stdio stream. - * The caller must have already opened the stream, and is responsible - * for closing it after finishing compression. + * The caller must have already opened the stream, + * and is responsible for closing it after finishing compression. */ GLOBAL(void) diff --git a/uppsrc/plugin/jpg/lib/jdatasrc.c b/uppsrc/plugin/jpg/lib/jdatasrc.c index 77fd76fe0..5153ed7f9 100644 --- a/uppsrc/plugin/jpg/lib/jdatasrc.c +++ b/uppsrc/plugin/jpg/lib/jdatasrc.c @@ -2,7 +2,7 @@ * jdatasrc.c * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2009-2019 by Guido Vollbeding. + * Modified 2009-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -23,18 +23,18 @@ /* Expanded data source object for stdio input */ +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ + typedef struct { struct jpeg_source_mgr pub; /* public fields */ FILE * infile; /* source stream */ - JOCTET * buffer; /* start of buffer */ + JOCTET buffer[INPUT_BUF_SIZE]; /* input buffer */ boolean start_of_file; /* have we gotten any data yet? */ } my_source_mgr; typedef my_source_mgr * my_src_ptr; -#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ - /* * Initialize source --- called by jpeg_read_header @@ -204,8 +204,8 @@ term_source (j_decompress_ptr cinfo) /* * Prepare for input from a stdio stream. - * The caller must have already opened the stream, and is responsible - * for closing it after finishing decompression. + * The caller must have already opened the stream, + * and is responsible for closing it after finishing decompression. */ GLOBAL(void) @@ -213,19 +213,16 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) { my_src_ptr src; - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling jpeg_stdio_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) + /* The source object including the input buffer is made permanent so that + * a series of JPEG images can be read from the same file by calling + * jpeg_stdio_src only before the first one. (If we discarded the buffer + * at the end of one image, we'd likely lose the start of the next one.) * This makes it unsafe to use this manager and a different source * manager serially with the same JPEG object. Caveat programmer. */ if (cinfo->src == NULL) { /* first time for this JPEG object? */ cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_source_mgr)); - src = (my_src_ptr) cinfo->src; - src->buffer = (JOCTET *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * SIZEOF(JOCTET)); } src = (my_src_ptr) cinfo->src; diff --git a/uppsrc/plugin/jpg/lib/jdcolor.c b/uppsrc/plugin/jpg/lib/jdcolor.c index e07b75c22..cf811a992 100644 --- a/uppsrc/plugin/jpg/lib/jdcolor.c +++ b/uppsrc/plugin/jpg/lib/jdcolor.c @@ -2,7 +2,7 @@ * jdcolor.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2011-2020 by Guido Vollbeding. + * Modified 2011-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -32,7 +32,9 @@ typedef struct { INT32 * Cb_g_tab; /* => table for Cb to G conversion */ /* Private state for RGB->Y conversion */ - INT32 * rgb_y_tab; /* => table for RGB to Y conversion */ + INT32 * R_y_tab; /* => table for R to Y conversion */ + INT32 * G_y_tab; /* => table for G to Y conversion */ + INT32 * B_y_tab; /* => table for B to Y conversion */ } my_color_deconverter; typedef my_color_deconverter * my_cconvert_ptr; @@ -87,29 +89,17 @@ typedef my_color_deconverter * my_cconvert_ptr; * by precalculating the constants times Cb and Cr for all possible values. * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); * for 9-bit to 12-bit samples it is still acceptable. It's not very - * reasonable for 16-bit samples, but if you want lossless storage you - * shouldn't be changing colorspace anyway. - * The Cr=>R and Cb=>B values can be rounded to integers in advance; the - * values for the G calculation are left scaled up, since we must add them - * together before rounding. + * reasonable for 16-bit samples, but if you want lossless storage + * you shouldn't be changing colorspace anyway. + * The Cr=>R and Cb=>B values can be rounded to integers in advance; + * the values for the G calculation are left scaled up, + * since we must add them together before rounding. */ #define SCALEBITS 16 /* speediest right-shift on some machines */ #define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) #define FIX(x) ((INT32) ((x) * (1L<Y conversion and divide it up into - * three parts, instead of doing three alloc_small requests. This lets us - * use a single table base address, which can be held in a register in the - * inner loops on many machines (more than can hold all three addresses, - * anyway). - */ - -#define R_Y_OFF 0 /* offset to R => Y section */ -#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ -#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ -#define TABLE_SIZE (3*(MAXJSAMPLE+1)) - /* * Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion. @@ -249,17 +239,19 @@ LOCAL(void) build_rgb_y_table (j_decompress_ptr cinfo) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - INT32 * rgb_y_tab; INT32 i; - /* Allocate and fill in the conversion tables. */ - cconvert->rgb_y_tab = rgb_y_tab = (INT32 *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, TABLE_SIZE * SIZEOF(INT32)); + cconvert->R_y_tab = (INT32 *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->G_y_tab = (INT32 *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->B_y_tab = (INT32 *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32)); for (i = 0; i <= MAXJSAMPLE; i++) { - rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i; - rgb_y_tab[i+G_Y_OFF] = FIX(0.587) * i; - rgb_y_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; + cconvert->R_y_tab[i] = FIX(0.299) * i; + cconvert->G_y_tab[i] = FIX(0.587) * i; + cconvert->B_y_tab[i] = FIX(0.114) * i + ONE_HALF; } } @@ -274,8 +266,10 @@ rgb_gray_convert (j_decompress_ptr cinfo, JSAMPARRAY output_buf, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_y_tab; + register INT32 y; + register INT32 * Rytab = cconvert->R_y_tab; + register INT32 * Gytab = cconvert->G_y_tab; + register INT32 * Bytab = cconvert->B_y_tab; register JSAMPROW outptr; register JSAMPROW inptr0, inptr1, inptr2; register JDIMENSION col; @@ -288,13 +282,10 @@ rgb_gray_convert (j_decompress_ptr cinfo, input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr0[col]); - g = GETJSAMPLE(inptr1[col]); - b = GETJSAMPLE(inptr2[col]); - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + y = Rytab[GETJSAMPLE(inptr0[col])]; + y += Gytab[GETJSAMPLE(inptr1[col])]; + y += Bytab[GETJSAMPLE(inptr2[col])]; + outptr[col] = (JSAMPLE) (y >> SCALEBITS); } } } @@ -354,7 +345,10 @@ rgb1_gray_convert (j_decompress_ptr cinfo, { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; register int r, g, b; - register INT32 * ctab = cconvert->rgb_y_tab; + register INT32 y; + register INT32 * Rytab = cconvert->R_y_tab; + register INT32 * Gytab = cconvert->G_y_tab; + register INT32 * Bytab = cconvert->B_y_tab; register JSAMPROW outptr; register JSAMPROW inptr0, inptr1, inptr2; register JDIMENSION col; @@ -373,12 +367,10 @@ rgb1_gray_convert (j_decompress_ptr cinfo, /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD * (modulo) operator is equivalent to the bitmask operator AND. */ - r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE; - b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE; - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + y = Rytab[(r + g - CENTERJSAMPLE) & MAXJSAMPLE]; + y += Gytab[g]; + y += Bytab[(b + g - CENTERJSAMPLE) & MAXJSAMPLE]; + outptr[col] = (JSAMPLE) (y >> SCALEBITS); } } } @@ -565,8 +557,10 @@ cmyk_yk_convert (j_decompress_ptr cinfo, JSAMPARRAY output_buf, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_y_tab; + register INT32 y; + register INT32 * Rytab = cconvert->R_y_tab; + register INT32 * Gytab = cconvert->G_y_tab; + register INT32 * Bytab = cconvert->B_y_tab; register JSAMPROW outptr; register JSAMPROW inptr0, inptr1, inptr2, inptr3; register JDIMENSION col; @@ -580,13 +574,10 @@ cmyk_yk_convert (j_decompress_ptr cinfo, input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - r = MAXJSAMPLE - GETJSAMPLE(inptr0[col]); - g = MAXJSAMPLE - GETJSAMPLE(inptr1[col]); - b = MAXJSAMPLE - GETJSAMPLE(inptr2[col]); - /* Y */ - outptr[0] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + y = Rytab[MAXJSAMPLE - GETJSAMPLE(inptr0[col])]; + y += Gytab[MAXJSAMPLE - GETJSAMPLE(inptr1[col])]; + y += Bytab[MAXJSAMPLE - GETJSAMPLE(inptr2[col])]; + outptr[0] = (JSAMPLE) (y >> SCALEBITS); /* K passes through unchanged */ outptr[1] = inptr3[col]; /* don't need GETJSAMPLE here */ outptr += 2; diff --git a/uppsrc/plugin/jpg/lib/jdct.h b/uppsrc/plugin/jpg/lib/jdct.h index 95994c5ea..b8f5b997c 100644 --- a/uppsrc/plugin/jpg/lib/jdct.h +++ b/uppsrc/plugin/jpg/lib/jdct.h @@ -2,7 +2,7 @@ * jdct.h * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2002-2019 by Guido Vollbeding. + * Modified 2002-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -158,7 +158,7 @@ typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ #define jpeg_idct_6x12 jRD6x12 #define jpeg_idct_5x10 jRD5x10 #define jpeg_idct_4x8 jRD4x8 -#define jpeg_idct_3x6 jRD3x8 +#define jpeg_idct_3x6 jRD3x6 #define jpeg_idct_2x4 jRD2x4 #define jpeg_idct_1x2 jRD1x2 #endif /* NEED_SHORT_EXTERNAL_NAMES */ diff --git a/uppsrc/plugin/jpg/lib/jdmerge.c b/uppsrc/plugin/jpg/lib/jdmerge.c index 92d7dfb20..d14ac81c7 100644 --- a/uppsrc/plugin/jpg/lib/jdmerge.c +++ b/uppsrc/plugin/jpg/lib/jdmerge.c @@ -2,7 +2,7 @@ * jdmerge.c * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2013-2020 by Guido Vollbeding. + * Modified 2013-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -20,17 +20,17 @@ * B = Y + K4 * Cb * only the Y term varies among the group of pixels corresponding to a pair * of chroma samples, so the rest of the terms can be calculated just once. - * At typical sampling ratios, this eliminates half or three-quarters of the - * multiplications needed for color conversion. + * At typical sampling ratios, this eliminates half or three-quarters + * of the multiplications needed for color conversion. * * This file currently provides implementations for the following cases: * YCC => RGB color conversion only (YCbCr or BG_YCC). * Sampling ratios of 2h1v or 2h2v. * No scaling needed at upsample time. * Corner-aligned (non-CCIR601) sampling alignment. - * Other special cases could be added, but in most applications these are - * the only common cases. (For uncommon cases we fall back on the more - * general code in jdsample.c and jdcolor.c.) + * Other special cases could be added, but in most applications these + * are the only common cases. (For uncommon cases we fall back on + * the more general code in jdsample.c and jdcolor.c.) */ #define JPEG_INTERNALS @@ -286,9 +286,9 @@ h2v1_merged_upsample (j_decompress_ptr cinfo, /* Do the chroma part of the calculation */ cb = GETJSAMPLE(*inptr1++); cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; + cred = Crrtab[cr]; /* Fetch 2 Y values and emit 2 pixels */ y = GETJSAMPLE(*inptr0++); outptr[RGB_RED] = range_limit[y + cred]; @@ -303,15 +303,14 @@ h2v1_merged_upsample (j_decompress_ptr cinfo, } /* If image width is odd, do the last output column separately */ if (cinfo->output_width & 1) { + y = GETJSAMPLE(*inptr0); cb = GETJSAMPLE(*inptr1); cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr0); - outptr[RGB_RED] = range_limit[y + cred]; - outptr[RGB_GREEN] = range_limit[y + cgreen]; - outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; + outptr[RGB_GREEN] = range_limit[y + + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS))]; + outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; } } @@ -350,9 +349,9 @@ h2v2_merged_upsample (j_decompress_ptr cinfo, /* Do the chroma part of the calculation */ cb = GETJSAMPLE(*inptr1++); cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; + cred = Crrtab[cr]; /* Fetch 4 Y values and emit 4 pixels */ y = GETJSAMPLE(*inptr00++); outptr0[RGB_RED] = range_limit[y + cred]; @@ -379,9 +378,9 @@ h2v2_merged_upsample (j_decompress_ptr cinfo, if (cinfo->output_width & 1) { cb = GETJSAMPLE(*inptr1); cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; + cred = Crrtab[cr]; y = GETJSAMPLE(*inptr00); outptr0[RGB_RED] = range_limit[y + cred]; outptr0[RGB_GREEN] = range_limit[y + cgreen]; diff --git a/uppsrc/plugin/jpg/lib/jinclude.h b/uppsrc/plugin/jpg/lib/jinclude.h index 3ed2463b8..510ac0fdb 100644 --- a/uppsrc/plugin/jpg/lib/jinclude.h +++ b/uppsrc/plugin/jpg/lib/jinclude.h @@ -2,7 +2,7 @@ * jinclude.h * * Copyright (C) 1991-1994, Thomas G. Lane. - * Modified 2017 by Guido Vollbeding. + * Modified 2017-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -11,8 +11,8 @@ * care of by the standard jconfig symbols, but on really weird systems * you may have to edit this file.) * - * NOTE: this file is NOT intended to be included by applications using the - * JPEG library. Most applications need only include jpeglib.h. + * NOTE: this file is NOT intended to be included by applications using + * the JPEG library. Most applications need only include jpeglib.h. */ @@ -87,11 +87,71 @@ * * Furthermore, macros are provided for fflush() and ferror() in order * to facilitate adaption by applications using an own FILE class. + * + * You can define your own custom file I/O functions in jconfig.h and + * #define JPEG_HAVE_FILE_IO_CUSTOM there to prevent redefinition here. + * + * You can #define JPEG_USE_FILE_IO_CUSTOM in jconfig.h to use custom file + * I/O functions implemented in Delphi VCL (Visual Component Library) + * in Vcl.Imaging.jpeg.pas for the TJPEGImage component utilizing + * the Delphi RTL (Run-Time Library) TMemoryStream component: + * + * procedure jpeg_stdio_src(var cinfo: jpeg_decompress_struct; + * input_file: TStream); external; + * + * procedure jpeg_stdio_dest(var cinfo: jpeg_compress_struct; + * output_file: TStream); external; + * + * function jfread(var buf; recsize, reccount: Integer; S: TStream): Integer; + * begin + * Result := S.Read(buf, recsize * reccount); + * end; + * + * function jfwrite(const buf; recsize, reccount: Integer; S: TStream): Integer; + * begin + * Result := S.Write(buf, recsize * reccount); + * end; + * + * function jfflush(S: TStream): Integer; + * begin + * Result := 0; + * end; + * + * function jferror(S: TStream): Integer; + * begin + * Result := 0; + * end; + * + * TMemoryStream of Delphi RTL has the distinctive feature to provide dynamic + * memory buffer management with a file/stream-based interface, particularly for + * the write (output) operation, which is easier to apply compared with direct + * implementations as given in jdatadst.c for memory destination. Those direct + * implementations of dynamic memory write tend to be more difficult to use, + * so providing an option like TMemoryStream may be a useful alternative. + * + * The CFile/CMemFile classes of the Microsoft Foundation Class (MFC) Library + * may be used in a similar fashion. */ +#ifndef JPEG_HAVE_FILE_IO_CUSTOM +#ifdef JPEG_USE_FILE_IO_CUSTOM +extern size_t jfread(void * __ptr, size_t __size, size_t __n, FILE * __stream); +extern size_t jfwrite(const void * __ptr, size_t __size, size_t __n, FILE * __stream); +extern int jfflush(FILE * __stream); +extern int jferror(FILE * __fp); + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) jfread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) jfwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFFLUSH(file) jfflush(file) +#define JFERROR(file) jferror(file) +#else #define JFREAD(file,buf,sizeofbuf) \ ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) #define JFWRITE(file,buf,sizeofbuf) \ ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) #define JFFLUSH(file) fflush(file) #define JFERROR(file) ferror(file) +#endif +#endif diff --git a/uppsrc/plugin/jpg/lib/jmemansi.c b/uppsrc/plugin/jpg/lib/jmemansi.c index 1156e5e02..b5da4743f 100644 --- a/uppsrc/plugin/jpg/lib/jmemansi.c +++ b/uppsrc/plugin/jpg/lib/jmemansi.c @@ -73,12 +73,10 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) * a slop factor of 5% or so. */ -#ifdef DEFAULT_MAX_MEM /* so can override from makefile */ -#undef DEFAULT_MAX_MEM +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ #endif -#define DEFAULT_MAX_MEM 100000000L //U++: Let us have this fixed at 100MB... - GLOBAL(long) jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, long max_bytes_needed, long already_allocated) diff --git a/uppsrc/plugin/jpg/lib/jmemdos.c b/uppsrc/plugin/jpg/lib/jmemdos.c deleted file mode 100644 index 60b45c693..000000000 --- a/uppsrc/plugin/jpg/lib/jmemdos.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - * jmemdos.c - * - * Copyright (C) 1992-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides an MS-DOS-compatible implementation of the system- - * dependent portion of the JPEG memory manager. Temporary data can be - * stored in extended or expanded memory as well as in regular DOS files. - * - * If you use this file, you must be sure that NEED_FAR_POINTERS is defined - * if you compile in a small-data memory model; it should NOT be defined if - * you use a large-data memory model. This file is not recommended if you - * are using a flat-memory-space 386 environment such as DJGCC or Watcom C. - * Also, this code will NOT work if struct fields are aligned on greater than - * 2-byte boundaries. - * - * Based on code contributed by Ge' Weijers. - */ - -/* - * If you have both extended and expanded memory, you may want to change the - * order in which they are tried in jopen_backing_store. On a 286 machine - * expanded memory is usually faster, since extended memory access involves - * an expensive protected-mode-and-back switch. On 386 and better, extended - * memory is usually faster. As distributed, the code tries extended memory - * first (what? not everyone has a 386? :-). - * - * You can disable use of extended/expanded memory entirely by altering these - * definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0). - */ - -#ifndef XMS_SUPPORTED -#define XMS_SUPPORTED 1 -#endif -#ifndef EMS_SUPPORTED -#define EMS_SUPPORTED 1 -#endif - - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef HAVE_STDLIB_H /* should declare these */ -extern void * malloc JPP((size_t size)); -extern void free JPP((void *ptr)); -extern char * getenv JPP((const char * name)); -#endif - -#ifdef NEED_FAR_POINTERS - -#ifdef __TURBOC__ -/* These definitions work for Borland C (Turbo C) */ -#include /* need farmalloc(), farfree() */ -#define far_malloc(x) farmalloc(x) -#define far_free(x) farfree(x) -#else -/* These definitions work for Microsoft C and compatible compilers */ -#include /* need _fmalloc(), _ffree() */ -#define far_malloc(x) _fmalloc(x) -#define far_free(x) _ffree(x) -#endif - -#else /* not NEED_FAR_POINTERS */ - -#define far_malloc(x) malloc(x) -#define far_free(x) free(x) - -#endif /* NEED_FAR_POINTERS */ - -#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ -#define READ_BINARY "r" -#else -#define READ_BINARY "rb" -#endif - -#ifndef USE_MSDOS_MEMMGR /* make sure user got configuration right */ - You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */ -#endif - -#if MAX_ALLOC_CHUNK >= 65535L /* make sure jconfig.h got this right */ - MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */ -#endif - - -/* - * Declarations for assembly-language support routines (see jmemdosa.asm). - * - * The functions are declared "far" as are all their pointer arguments; - * this ensures the assembly source code will work regardless of the - * compiler memory model. We assume "short" is 16 bits, "long" is 32. - */ - -typedef void far * XMSDRIVER; /* actually a pointer to code */ -typedef struct { /* registers for calling XMS driver */ - unsigned short ax, dx, bx; - void far * ds_si; - } XMScontext; -typedef struct { /* registers for calling EMS driver */ - unsigned short ax, dx, bx; - void far * ds_si; - } EMScontext; - -extern short far jdos_open JPP((short far * handle, char far * filename)); -extern short far jdos_close JPP((short handle)); -extern short far jdos_seek JPP((short handle, long offset)); -extern short far jdos_read JPP((short handle, void far * buffer, - unsigned short count)); -extern short far jdos_write JPP((short handle, void far * buffer, - unsigned short count)); -extern void far jxms_getdriver JPP((XMSDRIVER far *)); -extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *)); -extern short far jems_available JPP((void)); -extern void far jems_calldriver JPP((EMScontext far *)); - - -/* - * Selection of a file name for a temporary file. - * This is highly system-dependent, and you may want to customize it. - */ - -static int next_file_num; /* to distinguish among several temp files */ - -LOCAL(void) -select_file_name (char * fname) -{ - const char * env; - char * ptr; - FILE * tfile; - - /* Keep generating file names till we find one that's not in use */ - for (;;) { - /* Get temp directory name from environment TMP or TEMP variable; - * if none, use "." - */ - if ((env = (const char *) getenv("TMP")) == NULL) - if ((env = (const char *) getenv("TEMP")) == NULL) - env = "."; - if (*env == '\0') /* null string means "." */ - env = "."; - ptr = fname; /* copy name to fname */ - while (*env != '\0') - *ptr++ = *env++; - if (ptr[-1] != '\\' && ptr[-1] != '/') - *ptr++ = '\\'; /* append backslash if not in env variable */ - /* Append a suitable file name */ - next_file_num++; /* advance counter */ - sprintf(ptr, "JPG%03d.TMP", next_file_num); - /* Probe to see if file name is already in use */ - if ((tfile = fopen(fname, READ_BINARY)) == NULL) - break; - fclose(tfile); /* oops, it's there; close tfile & try again */ - } -} - - -/* - * Near-memory allocation and freeing are controlled by the regular library - * routines malloc() and free(). - */ - -GLOBAL(void *) -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * "Large" objects are allocated in far memory, if possible - */ - -GLOBAL(void FAR *) -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) far_malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - far_free(object); -} - - -/* - * This routine computes the total memory space available for allocation. - * It's impossible to do this in a portable way; our current solution is - * to make the user tell us (with a default value set at compile time). - * If you can actually get the available space, it's a good idea to subtract - * a slop factor of 5% or so. - */ - -#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ -#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */ -#endif - -GLOBAL(long) -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - return cinfo->mem->max_memory_to_use - already_allocated; -} - - -/* - * Backing store (temporary file) management. - * Backing store objects are only used when the value returned by - * jpeg_mem_available is less than the total space needed. You can dispense - * with these routines if you have plenty of virtual memory; see jmemnobs.c. - */ - -/* - * For MS-DOS we support three types of backing storage: - * 1. Conventional DOS files. We access these by direct DOS calls rather - * than via the stdio package. This provides a bit better performance, - * but the real reason is that the buffers to be read or written are FAR. - * The stdio library for small-data memory models can't cope with that. - * 2. Extended memory, accessed per the XMS V2.0 specification. - * 3. Expanded memory, accessed per the LIM/EMS 4.0 specification. - * You'll need copies of those specs to make sense of the related code. - * The specs are available by Internet FTP from the SIMTEL archives - * (oak.oakland.edu and its various mirror sites). See files - * pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip. - */ - - -/* - * Access methods for a DOS file. - */ - - -METHODDEF(void) -read_file_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (jdos_seek(info->handle.file_handle, file_offset)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ - if (byte_count > 65535L) /* safety check */ - ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); - if (jdos_read(info->handle.file_handle, buffer_address, - (unsigned short) byte_count)) - ERREXIT(cinfo, JERR_TFILE_READ); -} - - -METHODDEF(void) -write_file_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (jdos_seek(info->handle.file_handle, file_offset)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ - if (byte_count > 65535L) /* safety check */ - ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); - if (jdos_write(info->handle.file_handle, buffer_address, - (unsigned short) byte_count)) - ERREXIT(cinfo, JERR_TFILE_WRITE); -} - - -METHODDEF(void) -close_file_store (j_common_ptr cinfo, backing_store_ptr info) -{ - jdos_close(info->handle.file_handle); /* close the file */ - remove(info->temp_name); /* delete the file */ -/* If your system doesn't have remove(), try unlink() instead. - * remove() is the ANSI-standard name for this function, but - * unlink() was more common in pre-ANSI systems. - */ - TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); -} - - -LOCAL(boolean) -open_file_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - short handle; - - select_file_name(info->temp_name); - if (jdos_open((short far *) & handle, (char far *) info->temp_name)) { - /* might as well exit since jpeg_open_backing_store will fail anyway */ - ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); - return FALSE; - } - info->handle.file_handle = handle; - info->read_backing_store = read_file_store; - info->write_backing_store = write_file_store; - info->close_backing_store = close_file_store; - TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); - return TRUE; /* succeeded */ -} - - -/* - * Access methods for extended memory. - */ - -#if XMS_SUPPORTED - -static XMSDRIVER xms_driver; /* saved address of XMS driver */ - -typedef union { /* either long offset or real-mode pointer */ - long offset; - void far * ptr; - } XMSPTR; - -typedef struct { /* XMS move specification structure */ - long length; - XMSH src_handle; - XMSPTR src; - XMSH dst_handle; - XMSPTR dst; - } XMSspec; - -#define ODD(X) (((X) & 1L) != 0) - - -METHODDEF(void) -read_xms_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - XMScontext ctx; - XMSspec spec; - char endbuffer[2]; - - /* The XMS driver can't cope with an odd length, so handle the last byte - * specially if byte_count is odd. We don't expect this to be common. - */ - - spec.length = byte_count & (~ 1L); - spec.src_handle = info->handle.xms_handle; - spec.src.offset = file_offset; - spec.dst_handle = 0; - spec.dst.ptr = buffer_address; - - ctx.ds_si = (void far *) & spec; - ctx.ax = 0x0b00; /* EMB move */ - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - if (ctx.ax != 1) - ERREXIT(cinfo, JERR_XMS_READ); - - if (ODD(byte_count)) { - read_xms_store(cinfo, info, (void FAR *) endbuffer, - file_offset + byte_count - 1L, 2L); - ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0]; - } -} - - -METHODDEF(void) -write_xms_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - XMScontext ctx; - XMSspec spec; - char endbuffer[2]; - - /* The XMS driver can't cope with an odd length, so handle the last byte - * specially if byte_count is odd. We don't expect this to be common. - */ - - spec.length = byte_count & (~ 1L); - spec.src_handle = 0; - spec.src.ptr = buffer_address; - spec.dst_handle = info->handle.xms_handle; - spec.dst.offset = file_offset; - - ctx.ds_si = (void far *) & spec; - ctx.ax = 0x0b00; /* EMB move */ - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - if (ctx.ax != 1) - ERREXIT(cinfo, JERR_XMS_WRITE); - - if (ODD(byte_count)) { - read_xms_store(cinfo, info, (void FAR *) endbuffer, - file_offset + byte_count - 1L, 2L); - endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L]; - write_xms_store(cinfo, info, (void FAR *) endbuffer, - file_offset + byte_count - 1L, 2L); - } -} - - -METHODDEF(void) -close_xms_store (j_common_ptr cinfo, backing_store_ptr info) -{ - XMScontext ctx; - - ctx.dx = info->handle.xms_handle; - ctx.ax = 0x0a00; - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle); - /* we ignore any error return from the driver */ -} - - -LOCAL(boolean) -open_xms_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - XMScontext ctx; - - /* Get address of XMS driver */ - jxms_getdriver((XMSDRIVER far *) & xms_driver); - if (xms_driver == NULL) - return FALSE; /* no driver to be had */ - - /* Get version number, must be >= 2.00 */ - ctx.ax = 0x0000; - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - if (ctx.ax < (unsigned short) 0x0200) - return FALSE; - - /* Try to get space (expressed in kilobytes) */ - ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10); - ctx.ax = 0x0900; - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - if (ctx.ax != 1) - return FALSE; - - /* Succeeded, save the handle and away we go */ - info->handle.xms_handle = ctx.dx; - info->read_backing_store = read_xms_store; - info->write_backing_store = write_xms_store; - info->close_backing_store = close_xms_store; - TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx); - return TRUE; /* succeeded */ -} - -#endif /* XMS_SUPPORTED */ - - -/* - * Access methods for expanded memory. - */ - -#if EMS_SUPPORTED - -/* The EMS move specification structure requires word and long fields aligned - * at odd byte boundaries. Some compilers will align struct fields at even - * byte boundaries. While it's usually possible to force byte alignment, - * that causes an overall performance penalty and may pose problems in merging - * JPEG into a larger application. Instead we accept some rather dirty code - * here. Note this code would fail if the hardware did not allow odd-byte - * word & long accesses, but all 80x86 CPUs do. - */ - -typedef void far * EMSPTR; - -typedef union { /* EMS move specification structure */ - long length; /* It's easy to access first 4 bytes */ - char bytes[18]; /* Misaligned fields in here! */ - } EMSspec; - -/* Macros for accessing misaligned fields */ -#define FIELD_AT(spec,offset,type) (*((type *) &(spec.bytes[offset]))) -#define SRC_TYPE(spec) FIELD_AT(spec,4,char) -#define SRC_HANDLE(spec) FIELD_AT(spec,5,EMSH) -#define SRC_OFFSET(spec) FIELD_AT(spec,7,unsigned short) -#define SRC_PAGE(spec) FIELD_AT(spec,9,unsigned short) -#define SRC_PTR(spec) FIELD_AT(spec,7,EMSPTR) -#define DST_TYPE(spec) FIELD_AT(spec,11,char) -#define DST_HANDLE(spec) FIELD_AT(spec,12,EMSH) -#define DST_OFFSET(spec) FIELD_AT(spec,14,unsigned short) -#define DST_PAGE(spec) FIELD_AT(spec,16,unsigned short) -#define DST_PTR(spec) FIELD_AT(spec,14,EMSPTR) - -#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */ - -#define HIBYTE(W) (((W) >> 8) & 0xFF) -#define LOBYTE(W) ((W) & 0xFF) - - -METHODDEF(void) -read_ems_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - EMScontext ctx; - EMSspec spec; - - spec.length = byte_count; - SRC_TYPE(spec) = 1; - SRC_HANDLE(spec) = info->handle.ems_handle; - SRC_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); - SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); - DST_TYPE(spec) = 0; - DST_HANDLE(spec) = 0; - DST_PTR(spec) = buffer_address; - - ctx.ds_si = (void far *) & spec; - ctx.ax = 0x5700; /* move memory region */ - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0) - ERREXIT(cinfo, JERR_EMS_READ); -} - - -METHODDEF(void) -write_ems_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - EMScontext ctx; - EMSspec spec; - - spec.length = byte_count; - SRC_TYPE(spec) = 0; - SRC_HANDLE(spec) = 0; - SRC_PTR(spec) = buffer_address; - DST_TYPE(spec) = 1; - DST_HANDLE(spec) = info->handle.ems_handle; - DST_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); - DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); - - ctx.ds_si = (void far *) & spec; - ctx.ax = 0x5700; /* move memory region */ - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0) - ERREXIT(cinfo, JERR_EMS_WRITE); -} - - -METHODDEF(void) -close_ems_store (j_common_ptr cinfo, backing_store_ptr info) -{ - EMScontext ctx; - - ctx.ax = 0x4500; - ctx.dx = info->handle.ems_handle; - jems_calldriver((EMScontext far *) & ctx); - TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle); - /* we ignore any error return from the driver */ -} - - -LOCAL(boolean) -open_ems_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - EMScontext ctx; - - /* Is EMS driver there? */ - if (! jems_available()) - return FALSE; - - /* Get status, make sure EMS is OK */ - ctx.ax = 0x4000; - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0) - return FALSE; - - /* Get version, must be >= 4.0 */ - ctx.ax = 0x4600; - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40) - return FALSE; - - /* Try to allocate requested space */ - ctx.ax = 0x4300; - ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE); - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0) - return FALSE; - - /* Succeeded, save the handle and away we go */ - info->handle.ems_handle = ctx.dx; - info->read_backing_store = read_ems_store; - info->write_backing_store = write_ems_store; - info->close_backing_store = close_ems_store; - TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx); - return TRUE; /* succeeded */ -} - -#endif /* EMS_SUPPORTED */ - - -/* - * Initial opening of a backing-store object. - */ - -GLOBAL(void) -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - /* Try extended memory, then expanded memory, then regular file. */ -#if XMS_SUPPORTED - if (open_xms_store(cinfo, info, total_bytes_needed)) - return; -#endif -#if EMS_SUPPORTED - if (open_ems_store(cinfo, info, total_bytes_needed)) - return; -#endif - if (open_file_store(cinfo, info, total_bytes_needed)) - return; - ERREXITS(cinfo, JERR_TFILE_CREATE, ""); -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. - */ - -GLOBAL(long) -jpeg_mem_init (j_common_ptr cinfo) -{ - next_file_num = 0; /* initialize temp file name generator */ - return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ -} - -GLOBAL(void) -jpeg_mem_term (j_common_ptr cinfo) -{ - /* Microsoft C, at least in v6.00A, will not successfully reclaim freed - * blocks of size > 32Kbytes unless we give it a kick in the rear, like so: - */ -#ifdef NEED_FHEAPMIN - _fheapmin(); -#endif -} diff --git a/uppsrc/plugin/jpg/lib/jmemmac.c b/uppsrc/plugin/jpg/lib/jmemmac.c deleted file mode 100644 index 106f9bea0..000000000 --- a/uppsrc/plugin/jpg/lib/jmemmac.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * jmemmac.c - * - * Copyright (C) 1992-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * jmemmac.c provides an Apple Macintosh implementation of the system- - * dependent portion of the JPEG memory manager. - * - * If you use jmemmac.c, then you must define USE_MAC_MEMMGR in the - * JPEG_INTERNALS part of jconfig.h. - * - * jmemmac.c uses the Macintosh toolbox routines NewPtr and DisposePtr - * instead of malloc and free. It accurately determines the amount of - * memory available by using CompactMem. Notice that if left to its - * own devices, this code can chew up all available space in the - * application's zone, with the exception of the rather small "slop" - * factor computed in jpeg_mem_available(). The application can ensure - * that more space is left over by reducing max_memory_to_use. - * - * Large images are swapped to disk using temporary files and System 7.0+'s - * temporary folder functionality. - * - * Note that jmemmac.c depends on two features of MacOS that were first - * introduced in System 7: FindFolder and the FSSpec-based calls. - * If your application uses jmemmac.c and is run under System 6 or earlier, - * and the jpeg library decides it needs a temporary file, it will abort, - * printing error messages about requiring System 7. (If no temporary files - * are created, it will run fine.) - * - * If you want to use jmemmac.c in an application that might be used with - * System 6 or earlier, then you should remove dependencies on FindFolder - * and the FSSpec calls. You will need to replace FindFolder with some - * other mechanism for finding a place to put temporary files, and you - * should replace the FSSpec calls with their HFS equivalents: - * - * FSpDelete -> HDelete - * FSpGetFInfo -> HGetFInfo - * FSpCreate -> HCreate - * FSpOpenDF -> HOpen *** Note: not HOpenDF *** - * FSMakeFSSpec -> (fill in spec by hand.) - * - * (Use HOpen instead of HOpenDF. HOpen is just a glue-interface to PBHOpen, - * which is on all HFS macs. HOpenDF is a System 7 addition which avoids the - * ages-old problem of names starting with a period.) - * - * Contributed by Sam Bushell (jsam@iagu.on.net) and - * Dan Gildor (gyld@in-touch.com). - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef USE_MAC_MEMMGR /* make sure user got configuration right */ - You forgot to define USE_MAC_MEMMGR in jconfig.h. /* deliberate syntax error */ -#endif - -#include /* we use the MacOS memory manager */ -#include /* we use the MacOS File stuff */ -#include /* we use the MacOS HFS stuff */ -#include /* for smSystemScript */ -#include /* we use Gestalt to test for specific functionality */ - -#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ -#define TEMP_FILE_NAME "JPG%03d.TMP" -#endif - -static int next_file_num; /* to distinguish among several temp files */ - - -/* - * Memory allocation and freeing are controlled by the MacOS library - * routines NewPtr() and DisposePtr(), which allocate fixed-address - * storage. Unfortunately, the IJG library isn't smart enough to cope - * with relocatable storage. - */ - -GLOBAL(void *) -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) NewPtr(sizeofobject); -} - -GLOBAL(void) -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - DisposePtr((Ptr) object); -} - - -/* - * "Large" objects are treated the same as "small" ones. - * NB: we include FAR keywords in the routine declarations simply for - * consistency with the rest of the IJG code; FAR should expand to empty - * on rational architectures like the Mac. - */ - -GLOBAL(void FAR *) -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) NewPtr(sizeofobject); -} - -GLOBAL(void) -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - DisposePtr((Ptr) object); -} - - -/* - * This routine computes the total memory space available for allocation. - */ - -GLOBAL(long) -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - long limit = cinfo->mem->max_memory_to_use - already_allocated; - long slop, mem; - - /* Don't ask for more than what application has told us we may use */ - if (max_bytes_needed > limit && limit > 0) - max_bytes_needed = limit; - /* Find whether there's a big enough free block in the heap. - * CompactMem tries to create a contiguous block of the requested size, - * and then returns the size of the largest free block (which could be - * much more or much less than we asked for). - * We add some slop to ensure we don't use up all available memory. - */ - slop = max_bytes_needed / 16 + 32768L; - mem = CompactMem(max_bytes_needed + slop) - slop; - if (mem < 0) - mem = 0; /* sigh, couldn't even get the slop */ - /* Don't take more than the application says we can have */ - if (mem > limit && limit > 0) - mem = limit; - return mem; -} - - -/* - * Backing store (temporary file) management. - * Backing store objects are only used when the value returned by - * jpeg_mem_available is less than the total space needed. You can dispense - * with these routines if you have plenty of virtual memory; see jmemnobs.c. - */ - - -METHODDEF(void) -read_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - long bytes = byte_count; - long retVal; - - if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr ) - ERREXIT(cinfo, JERR_TFILE_SEEK); - - retVal = FSRead ( info->temp_file, &bytes, - (unsigned char *) buffer_address ); - if ( retVal != noErr || bytes != byte_count ) - ERREXIT(cinfo, JERR_TFILE_READ); -} - - -METHODDEF(void) -write_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - long bytes = byte_count; - long retVal; - - if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr ) - ERREXIT(cinfo, JERR_TFILE_SEEK); - - retVal = FSWrite ( info->temp_file, &bytes, - (unsigned char *) buffer_address ); - if ( retVal != noErr || bytes != byte_count ) - ERREXIT(cinfo, JERR_TFILE_WRITE); -} - - -METHODDEF(void) -close_backing_store (j_common_ptr cinfo, backing_store_ptr info) -{ - FSClose ( info->temp_file ); - FSpDelete ( &(info->tempSpec) ); -} - - -/* - * Initial opening of a backing-store object. - * - * This version uses FindFolder to find the Temporary Items folder, - * and puts the temporary file in there. - */ - -GLOBAL(void) -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - short tmpRef, vRefNum; - long dirID; - FInfo finderInfo; - FSSpec theSpec; - Str255 fName; - OSErr osErr; - long gestaltResponse = 0; - - /* Check that FSSpec calls are available. */ - osErr = Gestalt( gestaltFSAttr, &gestaltResponse ); - if ( ( osErr != noErr ) - || !( gestaltResponse & (1<temp_name, TEMP_FILE_NAME, next_file_num); - strcpy ( (Ptr)fName+1, info->temp_name ); - *fName = strlen (info->temp_name); - osErr = FSMakeFSSpec ( vRefNum, dirID, fName, &theSpec ); - - if ( (osErr = FSpGetFInfo ( &theSpec, &finderInfo ) ) != noErr ) - break; - } - - osErr = FSpCreate ( &theSpec, '????', '????', smSystemScript ); - if ( osErr != noErr ) - ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); - - osErr = FSpOpenDF ( &theSpec, fsRdWrPerm, &(info->temp_file) ); - if ( osErr != noErr ) - ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); - - info->tempSpec = theSpec; - - info->read_backing_store = read_backing_store; - info->write_backing_store = write_backing_store; - info->close_backing_store = close_backing_store; - TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. - */ - -GLOBAL(long) -jpeg_mem_init (j_common_ptr cinfo) -{ - next_file_num = 0; - - /* max_memory_to_use will be initialized to FreeMem()'s result; - * the calling application might later reduce it, for example - * to leave room to invoke multiple JPEG objects. - * Note that FreeMem returns the total number of free bytes; - * it may not be possible to allocate a single block of this size. - */ - return FreeMem(); -} - -GLOBAL(void) -jpeg_mem_term (j_common_ptr cinfo) -{ - /* no work */ -} diff --git a/uppsrc/plugin/jpg/lib/jmemname.c b/uppsrc/plugin/jpg/lib/jmemname.c deleted file mode 100644 index ed96dee1b..000000000 --- a/uppsrc/plugin/jpg/lib/jmemname.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * jmemname.c - * - * Copyright (C) 1992-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides a generic implementation of the system-dependent - * portion of the JPEG memory manager. This implementation assumes that - * you must explicitly construct a name for each temp file. - * Also, the problem of determining the amount of memory available - * is shoved onto the user. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ -extern void * malloc JPP((size_t size)); -extern void free JPP((void *ptr)); -#endif - -#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ -#define SEEK_SET 0 /* if not, assume 0 is correct */ -#endif - -#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ -#define READ_BINARY "r" -#define RW_BINARY "w+" -#else -#ifdef VMS /* VMS is very nonstandard */ -#define READ_BINARY "rb", "ctx=stm" -#define RW_BINARY "w+b", "ctx=stm" -#else /* standard ANSI-compliant case */ -#define READ_BINARY "rb" -#define RW_BINARY "w+b" -#endif -#endif - - -/* - * Selection of a file name for a temporary file. - * This is system-dependent! - * - * The code as given is suitable for most Unix systems, and it is easily - * modified for most non-Unix systems. Some notes: - * 1. The temp file is created in the directory named by TEMP_DIRECTORY. - * The default value is /usr/tmp, which is the conventional place for - * creating large temp files on Unix. On other systems you'll probably - * want to change the file location. You can do this by editing the - * #define, or (preferred) by defining TEMP_DIRECTORY in jconfig.h. - * - * 2. If you need to change the file name as well as its location, - * you can override the TEMP_FILE_NAME macro. (Note that this is - * actually a printf format string; it must contain %s and %d.) - * Few people should need to do this. - * - * 3. mktemp() is used to ensure that multiple processes running - * simultaneously won't select the same file names. If your system - * doesn't have mktemp(), define NO_MKTEMP to do it the hard way. - * (If you don't have , also define NO_ERRNO_H.) - * - * 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c - * will cause the temp files to be removed if you stop the program early. - */ - -#ifndef TEMP_DIRECTORY /* can override from jconfig.h or Makefile */ -#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */ -#endif - -static int next_file_num; /* to distinguish among several temp files */ - -#ifdef NO_MKTEMP - -#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ -#define TEMP_FILE_NAME "%sJPG%03d.TMP" -#endif - -#ifndef NO_ERRNO_H -#include /* to define ENOENT */ -#endif - -/* ANSI C specifies that errno is a macro, but on older systems it's more - * likely to be a plain int variable. And not all versions of errno.h - * bother to declare it, so we have to in order to be most portable. Thus: - */ -#ifndef errno -extern int errno; -#endif - - -LOCAL(void) -select_file_name (char * fname) -{ - FILE * tfile; - - /* Keep generating file names till we find one that's not in use */ - for (;;) { - next_file_num++; /* advance counter */ - sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); - if ((tfile = fopen(fname, READ_BINARY)) == NULL) { - /* fopen could have failed for a reason other than the file not - * being there; for example, file there but unreadable. - * If isn't available, then we cannot test the cause. - */ -#ifdef ENOENT - if (errno != ENOENT) - continue; -#endif - break; - } - fclose(tfile); /* oops, it's there; close tfile & try again */ - } -} - -#else /* ! NO_MKTEMP */ - -/* Note that mktemp() requires the initial filename to end in six X's */ -#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ -#define TEMP_FILE_NAME "%sJPG%dXXXXXX" -#endif - -LOCAL(void) -select_file_name (char * fname) -{ - next_file_num++; /* advance counter */ - sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); - mktemp(fname); /* make sure file name is unique */ - /* mktemp replaces the trailing XXXXXX with a unique string of characters */ -} - -#endif /* NO_MKTEMP */ - - -/* - * Memory allocation and freeing are controlled by the regular library - * routines malloc() and free(). - */ - -GLOBAL(void *) -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * "Large" objects are treated the same as "small" ones. - * NB: although we include FAR keywords in the routine declarations, - * this file won't actually work in 80x86 small/medium model; at least, - * you probably won't be able to process useful-size images in only 64KB. - */ - -GLOBAL(void FAR *) -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * This routine computes the total memory space available for allocation. - * It's impossible to do this in a portable way; our current solution is - * to make the user tell us (with a default value set at compile time). - * If you can actually get the available space, it's a good idea to subtract - * a slop factor of 5% or so. - */ - -#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ -#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ -#endif - -GLOBAL(long) -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - return cinfo->mem->max_memory_to_use - already_allocated; -} - - -/* - * Backing store (temporary file) management. - * Backing store objects are only used when the value returned by - * jpeg_mem_available is less than the total space needed. You can dispense - * with these routines if you have plenty of virtual memory; see jmemnobs.c. - */ - - -METHODDEF(void) -read_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (fseek(info->temp_file, file_offset, SEEK_SET)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - if (JFREAD(info->temp_file, buffer_address, byte_count) - != (size_t) byte_count) - ERREXIT(cinfo, JERR_TFILE_READ); -} - - -METHODDEF(void) -write_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (fseek(info->temp_file, file_offset, SEEK_SET)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - if (JFWRITE(info->temp_file, buffer_address, byte_count) - != (size_t) byte_count) - ERREXIT(cinfo, JERR_TFILE_WRITE); -} - - -METHODDEF(void) -close_backing_store (j_common_ptr cinfo, backing_store_ptr info) -{ - fclose(info->temp_file); /* close the file */ - unlink(info->temp_name); /* delete the file */ -/* If your system doesn't have unlink(), use remove() instead. - * remove() is the ANSI-standard name for this function, but if - * your system was ANSI you'd be using jmemansi.c, right? - */ - TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); -} - - -/* - * Initial opening of a backing-store object. - */ - -GLOBAL(void) -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - select_file_name(info->temp_name); - if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL) - ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); - info->read_backing_store = read_backing_store; - info->write_backing_store = write_backing_store; - info->close_backing_store = close_backing_store; - TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. - */ - -GLOBAL(long) -jpeg_mem_init (j_common_ptr cinfo) -{ - next_file_num = 0; /* initialize temp file name generator */ - return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ -} - -GLOBAL(void) -jpeg_mem_term (j_common_ptr cinfo) -{ - /* no work */ -} diff --git a/uppsrc/plugin/jpg/lib/jmemnobs.c b/uppsrc/plugin/jpg/lib/jmemnobs.c deleted file mode 100644 index a364cd822..000000000 --- a/uppsrc/plugin/jpg/lib/jmemnobs.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * jmemnobs.c - * - * Copyright (C) 1992-1996, Thomas G. Lane. - * Modified 2019 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides a really simple implementation of the system- - * dependent portion of the JPEG memory manager. This implementation - * assumes that no backing-store files are needed: all required space - * can be obtained from malloc(). - * This is very portable in the sense that it'll compile on almost anything, - * but you'd better have lots of main memory (or virtual memory) if you want - * to process big images. - * Note that the max_memory_to_use option is respected by this implementation. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ -extern void * malloc JPP((size_t size)); -extern void free JPP((void *ptr)); -#endif - - -/* - * Memory allocation and freeing are controlled by the regular library - * routines malloc() and free(). - */ - -GLOBAL(void *) -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * "Large" objects are treated the same as "small" ones. - * NB: although we include FAR keywords in the routine declarations, - * this file won't actually work in 80x86 small/medium model; at least, - * you probably won't be able to process useful-size images in only 64KB. - */ - -GLOBAL(void FAR *) -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * This routine computes the total memory space available for allocation. - */ - -GLOBAL(long) -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - if (cinfo->mem->max_memory_to_use) - return cinfo->mem->max_memory_to_use - already_allocated; - - /* Here we say, "we got all you want bud!" */ - return max_bytes_needed; -} - - -/* - * Backing store (temporary file) management. - * Since jpeg_mem_available always promised the moon, - * this should never be called and we can just error out. - */ - -GLOBAL(void) -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - ERREXIT(cinfo, JERR_NO_BACKING_STORE); -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. Here, there isn't any. - */ - -GLOBAL(long) -jpeg_mem_init (j_common_ptr cinfo) -{ - return 0; /* just set max_memory_to_use to 0 */ -} - -GLOBAL(void) -jpeg_mem_term (j_common_ptr cinfo) -{ - /* no work */ -} diff --git a/uppsrc/plugin/jpg/lib/jmorecfg.h b/uppsrc/plugin/jpg/lib/jmorecfg.h index 7407ac79b..f081f30df 100644 --- a/uppsrc/plugin/jpg/lib/jmorecfg.h +++ b/uppsrc/plugin/jpg/lib/jmorecfg.h @@ -2,7 +2,7 @@ * jmorecfg.h * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 1997-2013 by Guido Vollbeding. + * Modified 1997-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -351,8 +351,8 @@ typedef enum { FALSE = 0, TRUE = 1 } boolean; #define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN) */ +#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW) */ #define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ /* Note: if you selected more than 8-bit data precision, it is dangerous to * turn off ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only @@ -369,8 +369,8 @@ typedef enum { FALSE = 0, TRUE = 1 } boolean; #define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW)*/ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW) */ #define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ #define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ #undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ @@ -384,20 +384,31 @@ typedef enum { FALSE = 0, TRUE = 1 } boolean; /* * Ordering of RGB data in scanlines passed to or from the application. * If your application wants to deal with data in the order B,G,R, just - * change these macros. You can also deal with formats such as R,G,B,X - * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing - * the offsets will also change the order in which colormap data is organized. + * #define JPEG_USE_RGB_CUSTOM in jconfig.h, or define your own custom + * order in jconfig.h and #define JPEG_HAVE_RGB_CUSTOM. + * You can also deal with formats such as R,G,B,X (one extra byte per pixel) + * by changing RGB_PIXELSIZE. + * Note that changing the offsets will also change + * the order in which colormap data is organized. * RESTRICTIONS: * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. * 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE - * is not 3 (they don't understand about dummy color components!). So you - * can't use color quantization if you change that value. + * is not 3 (they don't understand about dummy color components!). + * So you can't use color quantization if you change that value. */ +#ifndef JPEG_HAVE_RGB_CUSTOM +#ifdef JPEG_USE_RGB_CUSTOM +#define RGB_RED 2 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 0 /* Offset of Blue */ +#else #define RGB_RED 0 /* Offset of Red in an RGB scanline element */ #define RGB_GREEN 1 /* Offset of Green */ #define RGB_BLUE 2 /* Offset of Blue */ +#endif #define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ +#endif /* Definitions for speed-related optimizations. */ diff --git a/uppsrc/plugin/jpg/lib/jpeglib.h b/uppsrc/plugin/jpg/lib/jpeglib.h index 523fdabc6..e8f0eff0d 100644 --- a/uppsrc/plugin/jpg/lib/jpeglib.h +++ b/uppsrc/plugin/jpg/lib/jpeglib.h @@ -2,7 +2,7 @@ * jpeglib.h * * Copyright (C) 1991-1998, Thomas G. Lane. - * Modified 2002-2020 by Guido Vollbeding. + * Modified 2002-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -39,7 +39,7 @@ extern "C" { #define JPEG_LIB_VERSION 90 /* Compatibility version 9.0 */ #define JPEG_LIB_VERSION_MAJOR 9 -#define JPEG_LIB_VERSION_MINOR 5 +#define JPEG_LIB_VERSION_MINOR 6 /* Various constants determining the sizes of things. diff --git a/uppsrc/plugin/jpg/lib/jpegtran.c b/uppsrc/plugin/jpg/lib/jpegtran.c deleted file mode 100644 index bfaa8aca7..000000000 --- a/uppsrc/plugin/jpg/lib/jpegtran.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - * jpegtran.c - * - * Copyright (C) 1995-2019, Thomas G. Lane, Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a command-line user interface for JPEG transcoding. - * It is very similar to cjpeg.c, and partly to djpeg.c, but provides - * lossless transcoding between different JPEG file formats. It also - * provides some lossless and sort-of-lossless transformations of JPEG data. - */ - -#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ -#include "transupp.h" /* Support routines for jpegtran */ -#include "jversion.h" /* for version message */ - -#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ -#ifdef __MWERKS__ -#include /* Metrowerks needs this */ -#include /* ... and this */ -#endif -#ifdef THINK_C -#include /* Think declares it here */ -#endif -#endif - - -/* - * Argument-parsing code. - * The switch parser is designed to be useful with DOS-style command line - * syntax, ie, intermixed switches and file names, where only the switches - * to the left of a given file name affect processing of that file. - * The main program in this file doesn't actually use this capability... - */ - - -static const char * progname; /* program name for error messages */ -static char * outfilename; /* for -outfile switch */ -static char * dropfilename; /* for -drop switch */ -static char * scaleoption; /* -scale switch */ -static JCOPY_OPTION copyoption; /* -copy switch */ -static jpeg_transform_info transformoption; /* image transformation options */ - - -LOCAL(void) -usage (void) -/* complain about bad command line */ -{ - fprintf(stderr, "usage: %s [switches] ", progname); -#ifdef TWO_FILE_COMMANDLINE - fprintf(stderr, "inputfile outputfile\n"); -#else - fprintf(stderr, "[inputfile]\n"); -#endif - - fprintf(stderr, "Switches (names may be abbreviated):\n"); - fprintf(stderr, " -copy none Copy no extra markers from source file\n"); - fprintf(stderr, " -copy comments Copy only comment markers (default)\n"); - fprintf(stderr, " -copy all Copy all extra markers\n"); -#ifdef ENTROPY_OPT_SUPPORTED - fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); -#endif -#ifdef C_PROGRESSIVE_SUPPORTED - fprintf(stderr, " -progressive Create progressive JPEG file\n"); -#endif - fprintf(stderr, "Switches for modifying the image:\n"); -#if TRANSFORMS_SUPPORTED - fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\n"); - fprintf(stderr, " -drop +X+Y filename Drop another image\n"); - fprintf(stderr, " -flip [horizontal|vertical] Mirror image (left-right or top-bottom)\n"); - fprintf(stderr, " -grayscale Reduce to grayscale (omit color data)\n"); - fprintf(stderr, " -perfect Fail if there is non-transformable edge blocks\n"); - fprintf(stderr, " -rotate [90|180|270] Rotate image (degrees clockwise)\n"); -#endif - fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\n"); -#if TRANSFORMS_SUPPORTED - fprintf(stderr, " -transpose Transpose image\n"); - fprintf(stderr, " -transverse Transverse transpose image\n"); - fprintf(stderr, " -trim Drop non-transformable edge blocks\n"); - fprintf(stderr, " with -drop: Requantize drop file to source file\n"); - fprintf(stderr, " -wipe WxH+X+Y Wipe (gray out) a rectangular subarea\n"); -#endif - fprintf(stderr, "Switches for advanced users:\n"); -#ifdef C_ARITH_CODING_SUPPORTED - fprintf(stderr, " -arithmetic Use arithmetic coding\n"); -#endif - fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); - fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); - fprintf(stderr, " -outfile name Specify name for output file\n"); - fprintf(stderr, " -verbose or -debug Emit debug output\n"); - fprintf(stderr, "Switches for wizards:\n"); -#ifdef C_MULTISCAN_FILES_SUPPORTED - fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); -#endif - exit(EXIT_FAILURE); -} - - -LOCAL(void) -select_transform (JXFORM_CODE transform) -/* Silly little routine to detect multiple transform options, - * which we can't handle. - */ -{ -#if TRANSFORMS_SUPPORTED - if (transformoption.transform == JXFORM_NONE || - transformoption.transform == transform) { - transformoption.transform = transform; - } else { - fprintf(stderr, "%s: can only do one image transformation at a time\n", - progname); - usage(); - } -#else - fprintf(stderr, "%s: sorry, image transformation was not compiled\n", - progname); - exit(EXIT_FAILURE); -#endif -} - - -LOCAL(int) -parse_switches (j_compress_ptr cinfo, int argc, char **argv, - int last_file_arg_seen, boolean for_real) -/* Parse optional switches. - * Returns argv[] index of first file-name argument (== argc if none). - * Any file names with indexes <= last_file_arg_seen are ignored; - * they have presumably been processed in a previous iteration. - * (Pass 0 for last_file_arg_seen on the first or only iteration.) - * for_real is FALSE on the first (dummy) pass; we may skip any expensive - * processing. - */ -{ - int argn; - char * arg; - boolean simple_progressive; - char * scansarg = NULL; /* saves -scans parm if any */ - - /* Set up default JPEG parameters. */ - simple_progressive = FALSE; - outfilename = NULL; - scaleoption = NULL; - copyoption = JCOPYOPT_DEFAULT; - transformoption.transform = JXFORM_NONE; - transformoption.perfect = FALSE; - transformoption.trim = FALSE; - transformoption.force_grayscale = FALSE; - transformoption.crop = FALSE; - cinfo->err->trace_level = 0; - - /* Scan command line options, adjust parameters */ - - for (argn = 1; argn < argc; argn++) { - arg = argv[argn]; - if (*arg != '-') { - /* Not a switch, must be a file name argument */ - if (argn <= last_file_arg_seen) { - outfilename = NULL; /* -outfile applies to just one input file */ - continue; /* ignore this name if previously processed */ - } - break; /* else done parsing switches */ - } - arg++; /* advance past switch marker character */ - - if (keymatch(arg, "arithmetic", 1)) { - /* Use arithmetic coding. */ -#ifdef C_ARITH_CODING_SUPPORTED - cinfo->arith_code = TRUE; -#else - fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", - progname); - exit(EXIT_FAILURE); -#endif - - } else if (keymatch(arg, "copy", 2)) { - /* Select which extra markers to copy. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - if (keymatch(argv[argn], "none", 1)) { - copyoption = JCOPYOPT_NONE; - } else if (keymatch(argv[argn], "comments", 1)) { - copyoption = JCOPYOPT_COMMENTS; - } else if (keymatch(argv[argn], "all", 1)) { - copyoption = JCOPYOPT_ALL; - } else - usage(); - - } else if (keymatch(arg, "crop", 2)) { - /* Perform lossless cropping. */ -#if TRANSFORMS_SUPPORTED - if (++argn >= argc) /* advance to next argument */ - usage(); - if (transformoption.crop /* reject multiple crop/drop/wipe requests */ || - ! jtransform_parse_crop_spec(&transformoption, argv[argn])) { - fprintf(stderr, "%s: bogus -crop argument '%s'\n", - progname, argv[argn]); - exit(EXIT_FAILURE); - } -#else - select_transform(JXFORM_NONE); /* force an error */ -#endif - - } else if (keymatch(arg, "drop", 2)) { -#if TRANSFORMS_SUPPORTED - if (++argn >= argc) /* advance to next argument */ - usage(); - if (transformoption.crop /* reject multiple crop/drop/wipe requests */ || - ! jtransform_parse_crop_spec(&transformoption, argv[argn]) || - transformoption.crop_width_set != JCROP_UNSET || - transformoption.crop_height_set != JCROP_UNSET) { - fprintf(stderr, "%s: bogus -drop argument '%s'\n", - progname, argv[argn]); - exit(EXIT_FAILURE); - } - if (++argn >= argc) /* advance to next argument */ - usage(); - dropfilename = argv[argn]; - select_transform(JXFORM_DROP); -#else - select_transform(JXFORM_NONE); /* force an error */ -#endif - - } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { - /* Enable debug printouts. */ - /* On first -d, print version identification */ - static boolean printed_version = FALSE; - - if (! printed_version) { - fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n", - JVERSION, JCOPYRIGHT); - printed_version = TRUE; - } - cinfo->err->trace_level++; - - } else if (keymatch(arg, "flip", 1)) { - /* Mirror left-right or top-bottom. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - if (keymatch(argv[argn], "horizontal", 1)) - select_transform(JXFORM_FLIP_H); - else if (keymatch(argv[argn], "vertical", 1)) - select_transform(JXFORM_FLIP_V); - else - usage(); - - } else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) { - /* Force to grayscale. */ -#if TRANSFORMS_SUPPORTED - transformoption.force_grayscale = TRUE; -#else - select_transform(JXFORM_NONE); /* force an error */ -#endif - - } else if (keymatch(arg, "maxmemory", 3)) { - /* Maximum memory in Kb (or Mb with 'm'). */ - long lval; - char ch = 'x'; - - if (++argn >= argc) /* advance to next argument */ - usage(); - if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) - usage(); - if (ch == 'm' || ch == 'M') - lval *= 1000L; - cinfo->mem->max_memory_to_use = lval * 1000L; - - } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) { - /* Enable entropy parm optimization. */ -#ifdef ENTROPY_OPT_SUPPORTED - cinfo->optimize_coding = TRUE; -#else - fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n", - progname); - exit(EXIT_FAILURE); -#endif - - } else if (keymatch(arg, "outfile", 4)) { - /* Set output file name. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - outfilename = argv[argn]; /* save it away for later use */ - - } else if (keymatch(arg, "perfect", 2)) { - /* Fail if there is any partial edge MCUs that the transform can't - * handle. */ - transformoption.perfect = TRUE; - - } else if (keymatch(arg, "progressive", 2)) { - /* Select simple progressive mode. */ -#ifdef C_PROGRESSIVE_SUPPORTED - simple_progressive = TRUE; - /* We must postpone execution until num_components is known. */ -#else - fprintf(stderr, "%s: sorry, progressive output was not compiled\n", - progname); - exit(EXIT_FAILURE); -#endif - - } else if (keymatch(arg, "restart", 1)) { - /* Restart interval in MCU rows (or in MCUs with 'b'). */ - long lval; - char ch = 'x'; - - if (++argn >= argc) /* advance to next argument */ - usage(); - if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) - usage(); - if (lval < 0 || lval > 65535L) - usage(); - if (ch == 'b' || ch == 'B') { - cinfo->restart_interval = (unsigned int) lval; - cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */ - } else { - cinfo->restart_in_rows = (int) lval; - /* restart_interval will be computed during startup */ - } - - } else if (keymatch(arg, "rotate", 2)) { - /* Rotate 90, 180, or 270 degrees (measured clockwise). */ - if (++argn >= argc) /* advance to next argument */ - usage(); - if (keymatch(argv[argn], "90", 2)) - select_transform(JXFORM_ROT_90); - else if (keymatch(argv[argn], "180", 3)) - select_transform(JXFORM_ROT_180); - else if (keymatch(argv[argn], "270", 3)) - select_transform(JXFORM_ROT_270); - else - usage(); - - } else if (keymatch(arg, "scale", 4)) { - /* Scale the output image by a fraction M/N. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - scaleoption = argv[argn]; - /* We must postpone processing until decompression startup. */ - - } else if (keymatch(arg, "scans", 1)) { - /* Set scan script. */ -#ifdef C_MULTISCAN_FILES_SUPPORTED - if (++argn >= argc) /* advance to next argument */ - usage(); - scansarg = argv[argn]; - /* We must postpone reading the file in case -progressive appears. */ -#else - fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n", - progname); - exit(EXIT_FAILURE); -#endif - - } else if (keymatch(arg, "transpose", 1)) { - /* Transpose (across UL-to-LR axis). */ - select_transform(JXFORM_TRANSPOSE); - - } else if (keymatch(arg, "transverse", 6)) { - /* Transverse transpose (across UR-to-LL axis). */ - select_transform(JXFORM_TRANSVERSE); - - } else if (keymatch(arg, "trim", 3)) { - /* Trim off any partial edge MCUs that the transform can't handle. */ - transformoption.trim = TRUE; - - } else if (keymatch(arg, "wipe", 1)) { -#if TRANSFORMS_SUPPORTED - if (++argn >= argc) /* advance to next argument */ - usage(); - if (transformoption.crop /* reject multiple crop/drop/wipe requests */ || - ! jtransform_parse_crop_spec(&transformoption, argv[argn])) { - fprintf(stderr, "%s: bogus -wipe argument '%s'\n", - progname, argv[argn]); - exit(EXIT_FAILURE); - } - select_transform(JXFORM_WIPE); -#else - select_transform(JXFORM_NONE); /* force an error */ -#endif - - } else { - usage(); /* bogus switch */ - } - } - - /* Post-switch-scanning cleanup */ - - if (for_real) { - -#ifdef C_PROGRESSIVE_SUPPORTED - if (simple_progressive) /* process -progressive; -scans can override */ - jpeg_simple_progression(cinfo); -#endif - -#ifdef C_MULTISCAN_FILES_SUPPORTED - if (scansarg != NULL) /* process -scans if it was present */ - if (! read_scan_script(cinfo, scansarg)) - usage(); -#endif - } - - return argn; /* return index of next arg (file name) */ -} - - -/* - * The main program. - */ - -int -main (int argc, char **argv) -{ - struct jpeg_decompress_struct srcinfo; - struct jpeg_error_mgr jsrcerr; -#if TRANSFORMS_SUPPORTED - struct jpeg_decompress_struct dropinfo; - struct jpeg_error_mgr jdroperr; - FILE * drop_file; -#endif - struct jpeg_compress_struct dstinfo; - struct jpeg_error_mgr jdsterr; -#ifdef PROGRESS_REPORT - struct cdjpeg_progress_mgr progress; -#endif - jvirt_barray_ptr * src_coef_arrays; - jvirt_barray_ptr * dst_coef_arrays; - int file_index; - /* We assume all-in-memory processing and can therefore use only a - * single file pointer for sequential input and output operation. - */ - FILE * fp; - - /* On Mac, fetch a command line. */ -#ifdef USE_CCOMMAND - argc = ccommand(&argv); -#endif - - progname = argv[0]; - if (progname == NULL || progname[0] == 0) - progname = "jpegtran"; /* in case C library doesn't provide it */ - - /* Initialize the JPEG decompression object with default error handling. */ - srcinfo.err = jpeg_std_error(&jsrcerr); - jpeg_create_decompress(&srcinfo); - /* Initialize the JPEG compression object with default error handling. */ - dstinfo.err = jpeg_std_error(&jdsterr); - jpeg_create_compress(&dstinfo); - - /* Now safe to enable signal catcher. - * Note: we assume only the decompression object will have virtual arrays. - */ -#ifdef NEED_SIGNAL_CATCHER - enable_signal_catcher((j_common_ptr) &srcinfo); -#endif - - /* Scan command line to find file names. - * It is convenient to use just one switch-parsing routine, but the switch - * values read here are mostly ignored; we will rescan the switches after - * opening the input file. Also note that most of the switches affect the - * destination JPEG object, so we parse into that and then copy over what - * needs to affect the source too. - */ - - file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE); - jsrcerr.trace_level = jdsterr.trace_level; - srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use; - -#ifdef TWO_FILE_COMMANDLINE - /* Must have either -outfile switch or explicit output file name */ - if (outfilename == NULL) { - if (file_index != argc-2) { - fprintf(stderr, "%s: must name one input and one output file\n", - progname); - usage(); - } - outfilename = argv[file_index+1]; - } else { - if (file_index != argc-1) { - fprintf(stderr, "%s: must name one input and one output file\n", - progname); - usage(); - } - } -#else - /* Unix style: expect zero or one file name */ - if (file_index < argc-1) { - fprintf(stderr, "%s: only one input file\n", progname); - usage(); - } -#endif /* TWO_FILE_COMMANDLINE */ - - /* Open the input file. */ - if (file_index < argc) { - if ((fp = fopen(argv[file_index], READ_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s for reading\n", progname, argv[file_index]); - exit(EXIT_FAILURE); - } - } else { - /* default input file is stdin */ - fp = read_stdin(); - } - -#if TRANSFORMS_SUPPORTED - /* Open the drop file. */ - if (dropfilename != NULL) { - if ((drop_file = fopen(dropfilename, READ_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s for reading\n", progname, dropfilename); - exit(EXIT_FAILURE); - } - dropinfo.err = jpeg_std_error(&jdroperr); - jpeg_create_decompress(&dropinfo); - jpeg_stdio_src(&dropinfo, drop_file); - } else { - drop_file = NULL; - } -#endif - -#ifdef PROGRESS_REPORT - start_progress_monitor((j_common_ptr) &dstinfo, &progress); -#endif - - /* Specify data source for decompression */ - jpeg_stdio_src(&srcinfo, fp); - - /* Enable saving of extra markers that we want to copy */ - jcopy_markers_setup(&srcinfo, copyoption); - - /* Read file header */ - (void) jpeg_read_header(&srcinfo, TRUE); - - /* Adjust default decompression parameters */ - if (scaleoption != NULL) - if (sscanf(scaleoption, "%u/%u", - &srcinfo.scale_num, &srcinfo.scale_denom) < 1) - usage(); - -#if TRANSFORMS_SUPPORTED - if (dropfilename != NULL) { - (void) jpeg_read_header(&dropinfo, TRUE); - transformoption.crop_width = dropinfo.image_width; - transformoption.crop_width_set = JCROP_POS; - transformoption.crop_height = dropinfo.image_height; - transformoption.crop_height_set = JCROP_POS; - transformoption.drop_ptr = &dropinfo; - } -#endif - - /* Any space needed by a transform option must be requested before - * jpeg_read_coefficients so that memory allocation will be done right. - */ -#if TRANSFORMS_SUPPORTED - /* Fail right away if -perfect is given and transformation is not perfect. - */ - if (!jtransform_request_workspace(&srcinfo, &transformoption)) { - fprintf(stderr, "%s: transformation is not perfect\n", progname); - exit(EXIT_FAILURE); - } -#endif - - /* Read source file as DCT coefficients */ - src_coef_arrays = jpeg_read_coefficients(&srcinfo); - -#if TRANSFORMS_SUPPORTED - if (dropfilename != NULL) { - transformoption.drop_coef_arrays = jpeg_read_coefficients(&dropinfo); - } -#endif - - /* Initialize destination compression parameters from source values */ - jpeg_copy_critical_parameters(&srcinfo, &dstinfo); - - /* Adjust destination parameters if required by transform options; - * also find out which set of coefficient arrays will hold the output. - */ -#if TRANSFORMS_SUPPORTED - dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo, - src_coef_arrays, - &transformoption); -#else - dst_coef_arrays = src_coef_arrays; -#endif - - /* Close input file, if we opened it. - * Note: we assume that jpeg_read_coefficients consumed all input - * until JPEG_REACHED_EOI, and that jpeg_finish_decompress will - * only consume more while (! cinfo->inputctl->eoi_reached). - * We cannot call jpeg_finish_decompress here since we still need the - * virtual arrays allocated from the source object for processing. - */ - if (fp != stdin) - fclose(fp); - - /* Open the output file. */ - if (outfilename != NULL) { - if ((fp = fopen(outfilename, WRITE_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s for writing\n", progname, outfilename); - exit(EXIT_FAILURE); - } - } else { - /* default output file is stdout */ - fp = write_stdout(); - } - - /* Adjust default compression parameters by re-parsing the options */ - file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); - - /* Specify data destination for compression */ - jpeg_stdio_dest(&dstinfo, fp); - - /* Start compressor (note no image data is actually written here) */ - jpeg_write_coefficients(&dstinfo, dst_coef_arrays); - - /* Copy to the output file any extra markers that we want to preserve */ - jcopy_markers_execute(&srcinfo, &dstinfo, copyoption); - - /* Execute image transformation, if any */ -#if TRANSFORMS_SUPPORTED - jtransform_execute_transformation(&srcinfo, &dstinfo, - src_coef_arrays, - &transformoption); -#endif - - /* Finish compression and release memory */ - jpeg_finish_compress(&dstinfo); - jpeg_destroy_compress(&dstinfo); -#if TRANSFORMS_SUPPORTED - if (dropfilename != NULL) { - (void) jpeg_finish_decompress(&dropinfo); - jpeg_destroy_decompress(&dropinfo); - } -#endif - (void) jpeg_finish_decompress(&srcinfo); - jpeg_destroy_decompress(&srcinfo); - - /* Close output file, if we opened it */ - if (fp != stdout) - fclose(fp); -#if TRANSFORMS_SUPPORTED - if (drop_file != NULL) - fclose(drop_file); -#endif - -#ifdef PROGRESS_REPORT - end_progress_monitor((j_common_ptr) &dstinfo); -#endif - - /* All done. */ -#if TRANSFORMS_SUPPORTED - if (dropfilename != NULL) - exit(jsrcerr.num_warnings + jdroperr.num_warnings + - jdsterr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); -#endif - exit(jsrcerr.num_warnings + jdsterr.num_warnings ? - EXIT_WARNING : EXIT_SUCCESS); - return 0; /* suppress no-return-value warnings */ -} diff --git a/uppsrc/plugin/jpg/lib/jversion.h b/uppsrc/plugin/jpg/lib/jversion.h index 639d6bcb2..26fa8c517 100644 --- a/uppsrc/plugin/jpg/lib/jversion.h +++ b/uppsrc/plugin/jpg/lib/jversion.h @@ -1,7 +1,7 @@ /* * jversion.h * - * Copyright (C) 1991-2022, Thomas G. Lane, Guido Vollbeding. + * Copyright (C) 1991-2024, Thomas G. Lane, Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -9,6 +9,6 @@ */ -#define JVERSION "9e 16-Jan-2022" +#define JVERSION "9f 14-Jan-2024" -#define JCOPYRIGHT "Copyright (C) 2022, Thomas G. Lane, Guido Vollbeding" +#define JCOPYRIGHT "Copyright (C) 2024, Thomas G. Lane, Guido Vollbeding" diff --git a/uppsrc/plugin/jpg/lib/rdjpgcom.c b/uppsrc/plugin/jpg/lib/rdjpgcom.c deleted file mode 100644 index 371915474..000000000 --- a/uppsrc/plugin/jpg/lib/rdjpgcom.c +++ /dev/null @@ -1,515 +0,0 @@ -/* - * rdjpgcom.c - * - * Copyright (C) 1994-1997, Thomas G. Lane. - * Modified 2009 by Bill Allombert, Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a very simple stand-alone application that displays - * the text in COM (comment) markers in a JFIF file. - * This may be useful as an example of the minimum logic needed to parse - * JPEG markers. - */ - -#define JPEG_CJPEG_DJPEG /* to get the command-line config symbols */ -#include "jinclude.h" /* get auto-config symbols, */ - -#ifdef HAVE_LOCALE_H -#include /* Bill Allombert: use locale for isprint */ -#endif -#include /* to declare isupper(), tolower() */ -#ifdef USE_SETMODE -#include /* to declare setmode()'s parameter macros */ -/* If you have setmode() but not , just delete this line: */ -#include /* to declare setmode() */ -#endif - -#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ -#ifdef __MWERKS__ -#include /* Metrowerks needs this */ -#include /* ... and this */ -#endif -#ifdef THINK_C -#include /* Think declares it here */ -#endif -#endif - -#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ -#define READ_BINARY "r" -#else -#ifdef VMS /* VMS is very nonstandard */ -#define READ_BINARY "rb", "ctx=stm" -#else /* standard ANSI-compliant case */ -#define READ_BINARY "rb" -#endif -#endif - -#ifndef EXIT_FAILURE /* define exit() codes if not provided */ -#define EXIT_FAILURE 1 -#endif -#ifndef EXIT_SUCCESS -#ifdef VMS -#define EXIT_SUCCESS 1 /* VMS is very nonstandard */ -#else -#define EXIT_SUCCESS 0 -#endif -#endif - - -/* - * These macros are used to read the input file. - * To reuse this code in another application, you might need to change these. - */ - -static FILE * infile; /* input JPEG file */ - -/* Return next input byte, or EOF if no more */ -#define NEXTBYTE() getc(infile) - - -/* Error exit handler */ -#define ERREXIT(msg) (fprintf(stderr, "%s\n", msg), exit(EXIT_FAILURE)) - - -/* Read one byte, testing for EOF */ -static int -read_1_byte (void) -{ - int c; - - c = NEXTBYTE(); - if (c == EOF) - ERREXIT("Premature EOF in JPEG file"); - return c; -} - -/* Read 2 bytes, convert to unsigned int */ -/* All 2-byte quantities in JPEG markers are MSB first */ -static unsigned int -read_2_bytes (void) -{ - int c1, c2; - - c1 = NEXTBYTE(); - if (c1 == EOF) - ERREXIT("Premature EOF in JPEG file"); - c2 = NEXTBYTE(); - if (c2 == EOF) - ERREXIT("Premature EOF in JPEG file"); - return (((unsigned int) c1) << 8) + ((unsigned int) c2); -} - - -/* - * JPEG markers consist of one or more 0xFF bytes, followed by a marker - * code byte (which is not an FF). Here are the marker codes of interest - * in this program. (See jdmarker.c for a more complete list.) - */ - -#define M_SOF0 0xC0 /* Start Of Frame N */ -#define M_SOF1 0xC1 /* N indicates which compression process */ -#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ -#define M_SOF3 0xC3 -#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ -#define M_SOF6 0xC6 -#define M_SOF7 0xC7 -#define M_SOF9 0xC9 -#define M_SOF10 0xCA -#define M_SOF11 0xCB -#define M_SOF13 0xCD -#define M_SOF14 0xCE -#define M_SOF15 0xCF -#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */ -#define M_EOI 0xD9 /* End Of Image (end of datastream) */ -#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ -#define M_APP0 0xE0 /* Application-specific marker, type N */ -#define M_APP12 0xEC /* (we don't bother to list all 16 APPn's) */ -#define M_COM 0xFE /* COMment */ - - -/* - * Find the next JPEG marker and return its marker code. - * We expect at least one FF byte, possibly more if the compressor used FFs - * to pad the file. - * There could also be non-FF garbage between markers. The treatment of such - * garbage is unspecified; we choose to skip over it but emit a warning msg. - * NB: this routine must not be used after seeing SOS marker, since it will - * not deal correctly with FF/00 sequences in the compressed image data... - */ - -static int -next_marker (void) -{ - int c; - int discarded_bytes = 0; - - /* Find 0xFF byte; count and skip any non-FFs. */ - c = read_1_byte(); - while (c != 0xFF) { - discarded_bytes++; - c = read_1_byte(); - } - /* Get marker code byte, swallowing any duplicate FF bytes. Extra FFs - * are legal as pad bytes, so don't count them in discarded_bytes. - */ - do { - c = read_1_byte(); - } while (c == 0xFF); - - if (discarded_bytes != 0) { - fprintf(stderr, "Warning: garbage data found in JPEG file\n"); - } - - return c; -} - - -/* - * Read the initial marker, which should be SOI. - * For a JFIF file, the first two bytes of the file should be literally - * 0xFF M_SOI. To be more general, we could use next_marker, but if the - * input file weren't actually JPEG at all, next_marker might read the whole - * file and then return a misleading error message... - */ - -static int -first_marker (void) -{ - int c1, c2; - - c1 = NEXTBYTE(); - c2 = NEXTBYTE(); - if (c1 != 0xFF || c2 != M_SOI) - ERREXIT("Not a JPEG file"); - return c2; -} - - -/* - * Most types of marker are followed by a variable-length parameter segment. - * This routine skips over the parameters for any marker we don't otherwise - * want to process. - * Note that we MUST skip the parameter segment explicitly in order not to - * be fooled by 0xFF bytes that might appear within the parameter segment; - * such bytes do NOT introduce new markers. - */ - -static void -skip_variable (void) -/* Skip over an unknown or uninteresting variable-length marker */ -{ - unsigned int length; - - /* Get the marker parameter length count */ - length = read_2_bytes(); - /* Length includes itself, so must be at least 2 */ - if (length < 2) - ERREXIT("Erroneous JPEG marker length"); - length -= 2; - /* Skip over the remaining bytes */ - while (length > 0) { - (void) read_1_byte(); - length--; - } -} - - -/* - * Process a COM marker. - * We want to print out the marker contents as legible text; - * we must guard against non-text junk and varying newline representations. - */ - -static void -process_COM (int raw) -{ - unsigned int length; - int ch; - int lastch = 0; - - /* Bill Allombert: set locale properly for isprint */ -#ifdef HAVE_LOCALE_H - setlocale(LC_CTYPE, ""); -#endif - - /* Get the marker parameter length count */ - length = read_2_bytes(); - /* Length includes itself, so must be at least 2 */ - if (length < 2) - ERREXIT("Erroneous JPEG marker length"); - length -= 2; - - while (length > 0) { - ch = read_1_byte(); - if (raw) { - putc(ch, stdout); - /* Emit the character in a readable form. - * Nonprintables are converted to \nnn form, - * while \ is converted to \\. - * Newlines in CR, CR/LF, or LF form will be printed as one newline. - */ - } else if (ch == '\r') { - printf("\n"); - } else if (ch == '\n') { - if (lastch != '\r') - printf("\n"); - } else if (ch == '\\') { - printf("\\\\"); - } else if (isprint(ch)) { - putc(ch, stdout); - } else { - printf("\\%03o", ch); - } - lastch = ch; - length--; - } - printf("\n"); - - /* Bill Allombert: revert to C locale */ -#ifdef HAVE_LOCALE_H - setlocale(LC_CTYPE, "C"); -#endif -} - - -/* - * Process a SOFn marker. - * This code is only needed if you want to know the image dimensions... - */ - -static void -process_SOFn (int marker) -{ - unsigned int length; - unsigned int image_height, image_width; - int data_precision, num_components; - const char * process; - int ci; - - length = read_2_bytes(); /* usual parameter length count */ - - data_precision = read_1_byte(); - image_height = read_2_bytes(); - image_width = read_2_bytes(); - num_components = read_1_byte(); - - switch (marker) { - case M_SOF0: process = "Baseline"; break; - case M_SOF1: process = "Extended sequential"; break; - case M_SOF2: process = "Progressive"; break; - case M_SOF3: process = "Lossless"; break; - case M_SOF5: process = "Differential sequential"; break; - case M_SOF6: process = "Differential progressive"; break; - case M_SOF7: process = "Differential lossless"; break; - case M_SOF9: process = "Extended sequential, arithmetic coding"; break; - case M_SOF10: process = "Progressive, arithmetic coding"; break; - case M_SOF11: process = "Lossless, arithmetic coding"; break; - case M_SOF13: process = "Differential sequential, arithmetic coding"; break; - case M_SOF14: process = "Differential progressive, arithmetic coding"; break; - case M_SOF15: process = "Differential lossless, arithmetic coding"; break; - default: process = "Unknown"; break; - } - - printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n", - image_width, image_height, num_components, data_precision); - printf("JPEG process: %s\n", process); - - if (length != (unsigned int) (8 + num_components * 3)) - ERREXIT("Bogus SOF marker length"); - - for (ci = 0; ci < num_components; ci++) { - (void) read_1_byte(); /* Component ID code */ - (void) read_1_byte(); /* H, V sampling factors */ - (void) read_1_byte(); /* Quantization table number */ - } -} - - -/* - * Parse the marker stream until SOS or EOI is seen; - * display any COM markers. - * While the companion program wrjpgcom will always insert COM markers before - * SOFn, other implementations might not, so we scan to SOS before stopping. - * If we were only interested in the image dimensions, we would stop at SOFn. - * (Conversely, if we only cared about COM markers, there would be no need - * for special code to handle SOFn; we could treat it like other markers.) - */ - -static int -scan_JPEG_header (int verbose, int raw) -{ - int marker; - - /* Expect SOI at start of file */ - if (first_marker() != M_SOI) - ERREXIT("Expected SOI marker first"); - - /* Scan miscellaneous markers until we reach SOS. */ - for (;;) { - marker = next_marker(); - switch (marker) { - /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be, - * treated as SOFn. C4 in particular is actually DHT. - */ - case M_SOF0: /* Baseline */ - case M_SOF1: /* Extended sequential, Huffman */ - case M_SOF2: /* Progressive, Huffman */ - case M_SOF3: /* Lossless, Huffman */ - case M_SOF5: /* Differential sequential, Huffman */ - case M_SOF6: /* Differential progressive, Huffman */ - case M_SOF7: /* Differential lossless, Huffman */ - case M_SOF9: /* Extended sequential, arithmetic */ - case M_SOF10: /* Progressive, arithmetic */ - case M_SOF11: /* Lossless, arithmetic */ - case M_SOF13: /* Differential sequential, arithmetic */ - case M_SOF14: /* Differential progressive, arithmetic */ - case M_SOF15: /* Differential lossless, arithmetic */ - if (verbose) - process_SOFn(marker); - else - skip_variable(); - break; - - case M_SOS: /* stop before hitting compressed data */ - return marker; - - case M_EOI: /* in case it's a tables-only JPEG stream */ - return marker; - - case M_COM: - process_COM(raw); - break; - - case M_APP12: - /* Some digital camera makers put useful textual information into - * APP12 markers, so we print those out too when in -verbose mode. - */ - if (verbose) { - printf("APP12 contains:\n"); - process_COM(raw); - } else - skip_variable(); - break; - - default: /* Anything else just gets skipped */ - skip_variable(); /* we assume it has a parameter count... */ - break; - } - } /* end loop */ -} - - -/* Command line parsing code */ - -static const char * progname; /* program name for error messages */ - - -static void -usage (void) -/* complain about bad command line */ -{ - fprintf(stderr, "rdjpgcom displays any textual comments in a JPEG file.\n"); - - fprintf(stderr, "Usage: %s [switches] [inputfile]\n", progname); - - fprintf(stderr, "Switches (names may be abbreviated):\n"); - fprintf(stderr, " -raw Display non-printable characters in comments (unsafe)\n"); - fprintf(stderr, " -verbose Also display dimensions of JPEG image\n"); - - exit(EXIT_FAILURE); -} - - -static int -keymatch (char * arg, const char * keyword, int minchars) -/* Case-insensitive matching of (possibly abbreviated) keyword switches. */ -/* keyword is the constant keyword (must be lower case already), */ -/* minchars is length of minimum legal abbreviation. */ -{ - register int ca, ck; - register int nmatched = 0; - - while ((ca = *arg++) != '\0') { - if ((ck = *keyword++) == '\0') - return 0; /* arg longer than keyword, no good */ - if (isupper(ca)) /* force arg to lcase (assume ck is already) */ - ca = tolower(ca); - if (ca != ck) - return 0; /* no good */ - nmatched++; /* count matched characters */ - } - /* reached end of argument; fail if it's too short for unique abbrev */ - if (nmatched < minchars) - return 0; - return 1; /* A-OK */ -} - - -/* - * The main program. - */ - -int -main (int argc, char **argv) -{ - int argn; - char * arg; - int verbose = 0, raw = 0; - - /* On Mac, fetch a command line. */ -#ifdef USE_CCOMMAND - argc = ccommand(&argv); -#endif - - progname = argv[0]; - if (progname == NULL || progname[0] == 0) - progname = "rdjpgcom"; /* in case C library doesn't provide it */ - - /* Parse switches, if any */ - for (argn = 1; argn < argc; argn++) { - arg = argv[argn]; - if (arg[0] != '-') - break; /* not switch, must be file name */ - arg++; /* advance over '-' */ - if (keymatch(arg, "verbose", 1)) { - verbose++; - } else if (keymatch(arg, "raw", 1)) { - raw = 1; - } else - usage(); - } - - /* Open the input file. */ - /* Unix style: expect zero or one file name */ - if (argn < argc-1) { - fprintf(stderr, "%s: only one input file\n", progname); - usage(); - } - if (argn < argc) { - if ((infile = fopen(argv[argn], READ_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); - exit(EXIT_FAILURE); - } - } else { - /* default input file is stdin */ -#ifdef USE_SETMODE /* need to hack file mode? */ - setmode(fileno(stdin), O_BINARY); -#endif -#ifdef USE_FDOPEN /* need to re-open in binary mode? */ - if ((infile = fdopen(fileno(stdin), READ_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open stdin\n", progname); - exit(EXIT_FAILURE); - } -#else - infile = stdin; -#endif - } - - /* Scan the JPEG headers. */ - (void) scan_JPEG_header(verbose, raw); - - /* All done. */ - exit(EXIT_SUCCESS); - return 0; /* suppress no-return-value warnings */ -} diff --git a/uppsrc/plugin/jpg/lib/transupp.c b/uppsrc/plugin/jpg/lib/transupp.c index 3c827ad80..c5aaee989 100644 --- a/uppsrc/plugin/jpg/lib/transupp.c +++ b/uppsrc/plugin/jpg/lib/transupp.c @@ -1,7 +1,7 @@ /* * transupp.c * - * Copyright (C) 1997-2019, Thomas G. Lane, Guido Vollbeding. + * Copyright (C) 1997-2023, Thomas G. Lane, Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -195,12 +195,11 @@ requant_comp (j_decompress_ptr cinfo, jpeg_component_info *compptr, jvirt_barray_ptr coef_array, JQUANT_TBL *qtblptr1) { JDIMENSION blk_x, blk_y; - int offset_y, k; + int offset_y, k, temp, qval; JQUANT_TBL *qtblptr; JBLOCKARRAY buffer; JBLOCKROW block; JCOEFPTR ptr; - JCOEF temp, qval; qtblptr = compptr->quant_table; for (blk_y = 0; blk_y < compptr->height_in_blocks; @@ -213,27 +212,27 @@ requant_comp (j_decompress_ptr cinfo, jpeg_component_info *compptr, for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) { ptr = block[blk_x]; for (k = 0; k < DCTSIZE2; k++) { - temp = qtblptr->quantval[k]; qval = qtblptr1->quantval[k]; - if (temp != qval) { - temp *= ptr[k]; - /* The following quantization code is a copy from jcdctmgr.c */ + if (qval == 0) continue; + temp = qtblptr->quantval[k]; + if (temp == qval) continue; + temp *= ptr[k]; + /* The following quantization code is a copy from jcdctmgr.c */ #ifdef FAST_DIVIDE #define DIVIDE_BY(a,b) a /= b #else #define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0 #endif - if (temp < 0) { - temp = -temp; - temp += qval>>1; /* for rounding */ - DIVIDE_BY(temp, qval); - temp = -temp; - } else { - temp += qval>>1; /* for rounding */ - DIVIDE_BY(temp, qval); - } - ptr[k] = temp; + if (temp < 0) { + temp = -temp; + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + temp = -temp; + } else { + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); } + ptr[k] = (JCOEF) temp; } } } @@ -248,11 +247,11 @@ largest_common_denominator(JCOEF a, JCOEF b) { JCOEF c; - do { + while (b) { c = a % b; a = b; b = c; - } while (c); + } return a; } diff --git a/uppsrc/plugin/jpg/lib/wrjpgcom.c b/uppsrc/plugin/jpg/lib/wrjpgcom.c deleted file mode 100644 index 69b47394a..000000000 --- a/uppsrc/plugin/jpg/lib/wrjpgcom.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - * wrjpgcom.c - * - * Copyright (C) 1994-1997, Thomas G. Lane. - * Modified 2015-2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a very simple stand-alone application that inserts - * user-supplied text as a COM (comment) marker in a JFIF file. - * This may be useful as an example of the minimum logic needed to parse - * JPEG markers. - */ - -#define JPEG_CJPEG_DJPEG /* to get the command-line config symbols */ -#include "jinclude.h" /* get auto-config symbols, */ - -#ifndef HAVE_STDLIB_H /* should declare malloc() */ -extern void * malloc (); -#endif -#include /* to declare isupper(), tolower() */ -#ifdef USE_SETMODE -#include /* to declare setmode()'s parameter macros */ -/* If you have setmode() but not , just delete this line: */ -#include /* to declare setmode() */ -#endif - -#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ -#ifdef __MWERKS__ -#include /* Metrowerks needs this */ -#include /* ... and this */ -#endif -#ifdef THINK_C -#include /* Think declares it here */ -#endif -#endif - -#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ -#define READ_BINARY "r" -#define WRITE_BINARY "w" -#else -#ifdef VMS /* VMS is very nonstandard */ -#define READ_BINARY "rb", "ctx=stm" -#define WRITE_BINARY "wb", "ctx=stm" -#else /* standard ANSI-compliant case */ -#define READ_BINARY "rb" -#define WRITE_BINARY "wb" -#endif -#endif - -#ifndef EXIT_FAILURE /* define exit() codes if not provided */ -#define EXIT_FAILURE 1 -#endif -#ifndef EXIT_SUCCESS -#ifdef VMS -#define EXIT_SUCCESS 1 /* VMS is very nonstandard */ -#else -#define EXIT_SUCCESS 0 -#endif -#endif - -/* Reduce this value if your malloc() can't allocate blocks up to 64K. - * On DOS, compiling in large model is usually a better solution. - */ - -#ifndef MAX_COM_LENGTH -#define MAX_COM_LENGTH 65000L /* must be <= 65533 in any case */ -#endif - - -/* - * These macros are used to read the input file and write the output file. - * To reuse this code in another application, you might need to change these. - */ - -static FILE * infile; /* input JPEG file */ - -/* Return next input byte, or EOF if no more */ -#define NEXTBYTE() getc(infile) - -static FILE * outfile; /* output JPEG file */ - -/* Emit an output byte */ -#define PUTBYTE(x) putc((x), outfile) - - -/* Error exit handler */ -#define ERREXIT(msg) (fprintf(stderr, "%s\n", msg), exit(EXIT_FAILURE)) - - -/* Read one byte, testing for EOF */ -static int -read_1_byte (void) -{ - int c; - - c = NEXTBYTE(); - if (c == EOF) - ERREXIT("Premature EOF in JPEG file"); - return c; -} - -/* Read 2 bytes, convert to unsigned int */ -/* All 2-byte quantities in JPEG markers are MSB first */ -static unsigned int -read_2_bytes (void) -{ - int c1, c2; - - c1 = NEXTBYTE(); - if (c1 == EOF) - ERREXIT("Premature EOF in JPEG file"); - c2 = NEXTBYTE(); - if (c2 == EOF) - ERREXIT("Premature EOF in JPEG file"); - return (((unsigned int) c1) << 8) + ((unsigned int) c2); -} - - -/* Routines to write data to output file */ - -static void -write_1_byte (int c) -{ - PUTBYTE(c); -} - -static void -write_2_bytes (unsigned int val) -{ - PUTBYTE((val >> 8) & 0xFF); - PUTBYTE(val & 0xFF); -} - -static void -write_marker (int marker) -{ - PUTBYTE(0xFF); - PUTBYTE(marker); -} - -static void -copy_rest_of_file (void) -{ - int c; - - while ((c = NEXTBYTE()) != EOF) - PUTBYTE(c); -} - - -/* - * JPEG markers consist of one or more 0xFF bytes, followed by a marker - * code byte (which is not an FF). Here are the marker codes of interest - * in this program. (See jdmarker.c for a more complete list.) - */ - -#define M_SOF0 0xC0 /* Start Of Frame N */ -#define M_SOF1 0xC1 /* N indicates which compression process */ -#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ -#define M_SOF3 0xC3 -#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ -#define M_SOF6 0xC6 -#define M_SOF7 0xC7 -#define M_SOF9 0xC9 -#define M_SOF10 0xCA -#define M_SOF11 0xCB -#define M_SOF13 0xCD -#define M_SOF14 0xCE -#define M_SOF15 0xCF -#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */ -#define M_EOI 0xD9 /* End Of Image (end of datastream) */ -#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ -#define M_COM 0xFE /* COMment */ - - -/* - * Find the next JPEG marker and return its marker code. - * We expect at least one FF byte, possibly more if the compressor used FFs - * to pad the file. (Padding FFs will NOT be replicated in the output file.) - * There could also be non-FF garbage between markers. The treatment of such - * garbage is unspecified; we choose to skip over it but emit a warning msg. - * NB: this routine must not be used after seeing SOS marker, since it will - * not deal correctly with FF/00 sequences in the compressed image data... - */ - -static int -next_marker (void) -{ - int c; - int discarded_bytes = 0; - - /* Find 0xFF byte; count and skip any non-FFs. */ - c = read_1_byte(); - while (c != 0xFF) { - discarded_bytes++; - c = read_1_byte(); - } - /* Get marker code byte, swallowing any duplicate FF bytes. Extra FFs - * are legal as pad bytes, so don't count them in discarded_bytes. - */ - do { - c = read_1_byte(); - } while (c == 0xFF); - - if (discarded_bytes != 0) { - fprintf(stderr, "Warning: garbage data found in JPEG file\n"); - } - - return c; -} - - -/* - * Read the initial marker, which should be SOI. - * For a JFIF file, the first two bytes of the file should be literally - * 0xFF M_SOI. To be more general, we could use next_marker, but if the - * input file weren't actually JPEG at all, next_marker might read the whole - * file and then return a misleading error message... - */ - -static int -first_marker (void) -{ - int c1, c2; - - c1 = NEXTBYTE(); - c2 = NEXTBYTE(); - if (c1 != 0xFF || c2 != M_SOI) - ERREXIT("Not a JPEG file"); - return c2; -} - - -/* - * Most types of marker are followed by a variable-length parameter segment. - * This routine skips over the parameters for any marker we don't otherwise - * want to process. - * Note that we MUST skip the parameter segment explicitly in order not to - * be fooled by 0xFF bytes that might appear within the parameter segment; - * such bytes do NOT introduce new markers. - */ - -static void -copy_variable (void) -/* Copy an unknown or uninteresting variable-length marker */ -{ - unsigned int length; - - /* Get the marker parameter length count */ - length = read_2_bytes(); - write_2_bytes(length); - /* Length includes itself, so must be at least 2 */ - if (length < 2) - ERREXIT("Erroneous JPEG marker length"); - length -= 2; - /* Copy the remaining bytes */ - while (length > 0) { - write_1_byte(read_1_byte()); - length--; - } -} - -static void -skip_variable (void) -/* Skip over an unknown or uninteresting variable-length marker */ -{ - unsigned int length; - - /* Get the marker parameter length count */ - length = read_2_bytes(); - /* Length includes itself, so must be at least 2 */ - if (length < 2) - ERREXIT("Erroneous JPEG marker length"); - length -= 2; - /* Skip over the remaining bytes */ - while (length > 0) { - (void) read_1_byte(); - length--; - } -} - - -/* - * Parse the marker stream until SOFn or EOI is seen; - * copy data to output, but discard COM markers unless keep_COM is true. - */ - -static int -scan_JPEG_header (int keep_COM) -{ - int marker; - - /* Expect SOI at start of file */ - if (first_marker() != M_SOI) - ERREXIT("Expected SOI marker first"); - write_marker(M_SOI); - - /* Scan miscellaneous markers until we reach SOFn. */ - for (;;) { - marker = next_marker(); - switch (marker) { - /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be, - * treated as SOFn. C4 in particular is actually DHT. - */ - case M_SOF0: /* Baseline */ - case M_SOF1: /* Extended sequential, Huffman */ - case M_SOF2: /* Progressive, Huffman */ - case M_SOF3: /* Lossless, Huffman */ - case M_SOF5: /* Differential sequential, Huffman */ - case M_SOF6: /* Differential progressive, Huffman */ - case M_SOF7: /* Differential lossless, Huffman */ - case M_SOF9: /* Extended sequential, arithmetic */ - case M_SOF10: /* Progressive, arithmetic */ - case M_SOF11: /* Lossless, arithmetic */ - case M_SOF13: /* Differential sequential, arithmetic */ - case M_SOF14: /* Differential progressive, arithmetic */ - case M_SOF15: /* Differential lossless, arithmetic */ - return marker; - - case M_SOS: /* should not see compressed data before SOF */ - ERREXIT("SOS without prior SOFn"); - break; - - case M_EOI: /* in case it's a tables-only JPEG stream */ - return marker; - - case M_COM: /* Existing COM: conditionally discard */ - if (keep_COM) { - write_marker(marker); - copy_variable(); - } else { - skip_variable(); - } - break; - - default: /* Anything else just gets copied */ - write_marker(marker); - copy_variable(); /* we assume it has a parameter count... */ - break; - } - } /* end loop */ -} - - -/* Command line parsing code */ - -static const char * progname; /* program name for error messages */ - - -static void -usage (void) -/* complain about bad command line */ -{ - fprintf(stderr, "wrjpgcom inserts a textual comment in a JPEG file.\n"); - fprintf(stderr, "You can add to or replace any existing comment(s).\n"); - - fprintf(stderr, "Usage: %s [switches] ", progname); -#ifdef TWO_FILE_COMMANDLINE - fprintf(stderr, "inputfile outputfile\n"); -#else - fprintf(stderr, "[inputfile]\n"); -#endif - - fprintf(stderr, "Switches (names may be abbreviated):\n"); - fprintf(stderr, " -replace Delete any existing comments\n"); - fprintf(stderr, " -comment \"text\" Insert comment with given text\n"); - fprintf(stderr, " -cfile name Read comment from named file\n"); - fprintf(stderr, "Notice that you must put quotes around the comment text\n"); - fprintf(stderr, "when you use -comment.\n"); - fprintf(stderr, "If you do not give either -comment or -cfile on the command line,\n"); - fprintf(stderr, "then the comment text is read from standard input.\n"); - fprintf(stderr, "It can be multiple lines, up to %u characters total.\n", - (unsigned int) MAX_COM_LENGTH); -#ifndef TWO_FILE_COMMANDLINE - fprintf(stderr, "You must specify an input JPEG file name when supplying\n"); - fprintf(stderr, "comment text from standard input.\n"); -#endif - - exit(EXIT_FAILURE); -} - - -static int -keymatch (char * arg, const char * keyword, int minchars) -/* Case-insensitive matching of (possibly abbreviated) keyword switches. */ -/* keyword is the constant keyword (must be lower case already), */ -/* minchars is length of minimum legal abbreviation. */ -{ - register int ca, ck; - register int nmatched = 0; - - while ((ca = *arg++) != '\0') { - if ((ck = *keyword++) == '\0') - return 0; /* arg longer than keyword, no good */ - if (isupper(ca)) /* force arg to lcase (assume ck is already) */ - ca = tolower(ca); - if (ca != ck) - return 0; /* no good */ - nmatched++; /* count matched characters */ - } - /* reached end of argument; fail if it's too short for unique abbrev */ - if (nmatched < minchars) - return 0; - return 1; /* A-OK */ -} - - -/* - * The main program. - */ - -int -main (int argc, char **argv) -{ - int argn; - char * arg; - int keep_COM = 1; - char * comment_arg = NULL; - FILE * comment_file = NULL; - unsigned int comment_length = 0; - int marker; - - /* On Mac, fetch a command line. */ -#ifdef USE_CCOMMAND - argc = ccommand(&argv); -#endif - - progname = argv[0]; - if (progname == NULL || progname[0] == 0) - progname = "wrjpgcom"; /* in case C library doesn't provide it */ - - /* Parse switches, if any */ - for (argn = 1; argn < argc; argn++) { - arg = argv[argn]; - if (arg[0] != '-') - break; /* not switch, must be file name */ - arg++; /* advance over '-' */ - if (keymatch(arg, "replace", 1)) { - keep_COM = 0; - } else if (keymatch(arg, "cfile", 2)) { - if (++argn >= argc) usage(); - if ((comment_file = fopen(argv[argn], "r")) == NULL) { - fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); - exit(EXIT_FAILURE); - } - } else if (keymatch(arg, "comment", 1)) { - if (++argn >= argc) usage(); - comment_arg = argv[argn]; - /* If the comment text starts with '"', then we are probably running - * under MS-DOG and must parse out the quoted string ourselves. Sigh. - */ - if (comment_arg[0] == '"') { - comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH); - if (comment_arg == NULL) - ERREXIT("Insufficient memory"); - if (strlen(argv[argn]+1) >= (size_t) MAX_COM_LENGTH) { - fprintf(stderr, "Comment text may not exceed %u bytes\n", - (unsigned int) MAX_COM_LENGTH); - exit(EXIT_FAILURE); - } - strcpy(comment_arg, argv[argn]+1); - for (;;) { - comment_length = (unsigned int) strlen(comment_arg); - if (comment_length > 0 && comment_arg[comment_length-1] == '"') { - comment_arg[comment_length-1] = '\0'; /* zap terminating quote */ - break; - } - if (++argn >= argc) - ERREXIT("Missing ending quote mark"); - if (strlen(comment_arg) + 1 + strlen(argv[argn]) >= - (size_t) MAX_COM_LENGTH) { - fprintf(stderr, "Comment text may not exceed %u bytes\n", - (unsigned int) MAX_COM_LENGTH); - exit(EXIT_FAILURE); - } - strcat(comment_arg, " "); - strcat(comment_arg, argv[argn]); - } - } else if (strlen(comment_arg) >= (size_t) MAX_COM_LENGTH) { - fprintf(stderr, "Comment text may not exceed %u bytes\n", - (unsigned int) MAX_COM_LENGTH); - exit(EXIT_FAILURE); - } - comment_length = (unsigned int) strlen(comment_arg); - } else - usage(); - } - - /* Cannot use both -comment and -cfile. */ - if (comment_arg != NULL && comment_file != NULL) - usage(); - /* If there is neither -comment nor -cfile, we will read the comment text - * from stdin; in this case there MUST be an input JPEG file name. - */ - if (comment_arg == NULL && comment_file == NULL && argn >= argc) - usage(); - - /* Open the input file. */ - if (argn < argc) { - if ((infile = fopen(argv[argn], READ_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); - exit(EXIT_FAILURE); - } - } else { - /* default input file is stdin */ -#ifdef USE_SETMODE /* need to hack file mode? */ - setmode(fileno(stdin), O_BINARY); -#endif -#ifdef USE_FDOPEN /* need to re-open in binary mode? */ - if ((infile = fdopen(fileno(stdin), READ_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open stdin\n", progname); - exit(EXIT_FAILURE); - } -#else - infile = stdin; -#endif - } - - /* Open the output file. */ -#ifdef TWO_FILE_COMMANDLINE - /* Must have explicit output file name */ - if (argn != argc-2) { - fprintf(stderr, "%s: must name one input and one output file\n", - progname); - usage(); - } - if ((outfile = fopen(argv[argn+1], WRITE_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s\n", progname, argv[argn+1]); - exit(EXIT_FAILURE); - } -#else - /* Unix style: expect zero or one file name */ - if (argn < argc-1) { - fprintf(stderr, "%s: only one input file\n", progname); - usage(); - } - /* default output file is stdout */ -#ifdef USE_SETMODE /* need to hack file mode? */ - setmode(fileno(stdout), O_BINARY); -#endif -#ifdef USE_FDOPEN /* need to re-open in binary mode? */ - if ((outfile = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open stdout\n", progname); - exit(EXIT_FAILURE); - } -#else - outfile = stdout; -#endif -#endif /* TWO_FILE_COMMANDLINE */ - - /* Collect comment text from comment_file or stdin, if necessary */ - if (comment_arg == NULL) { - FILE * src_file; - int c; - - comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH); - if (comment_arg == NULL) - ERREXIT("Insufficient memory"); - comment_length = 0; - src_file = (comment_file != NULL ? comment_file : stdin); - while ((c = getc(src_file)) != EOF) { - if (comment_length >= (unsigned int) MAX_COM_LENGTH) { - fprintf(stderr, "Comment text may not exceed %u bytes\n", - (unsigned int) MAX_COM_LENGTH); - exit(EXIT_FAILURE); - } - comment_arg[comment_length++] = (char) c; - } - if (comment_file != NULL) - fclose(comment_file); - } - - /* Copy JPEG headers until SOFn marker; - * we will insert the new comment marker just before SOFn. - * This (a) causes the new comment to appear after, rather than before, - * existing comments; and (b) ensures that comments come after any JFIF - * or JFXX markers, as required by the JFIF specification. - */ - marker = scan_JPEG_header(keep_COM); - /* Insert the new COM marker, but only if nonempty text has been supplied */ - if (comment_length > 0) { - write_marker(M_COM); - write_2_bytes(comment_length + 2); - while (comment_length > 0) { - write_1_byte(*comment_arg++); - comment_length--; - } - } - /* Duplicate the remainder of the source file. - * Note that any COM markers occuring after SOF will not be touched. - */ - write_marker(marker); - copy_rest_of_file(); - - /* All done. */ - exit(EXIT_SUCCESS); - return 0; /* suppress no-return-value warnings */ -}