cjpeg: Add -strict arg to treat warnings as fatal

This adds fault tolerance to the LZW-compressed GIF reader, which is
the only compression-side code that can throw warnings.
diff --git a/ChangeLog.md b/ChangeLog.md
index 8d9d31a..7902d46 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -25,6 +25,10 @@
 time.  This allows both AltiVec-equipped and non-AltiVec-equipped CPUs to be
 supported using the same build of libjpeg-turbo.
 
+5. cjpeg now accepts a `-strict` argument similar to that of djpeg and
+jpegtran, which causes the compressor to abort if an LZW-compressed GIF input
+image contains incomplete or corrupt image data.
+
 
 2.1.1
 =====
diff --git a/cjpeg.1 b/cjpeg.1
index 569dc3f..75a9cce 100644
--- a/cjpeg.1
+++ b/cjpeg.1
@@ -1,4 +1,4 @@
-.TH CJPEG 1 "4 November 2020"
+.TH CJPEG 1 "18 November 2021"
 .SH NAME
 cjpeg \- compress an image file to a JPEG file
 .SH SYNOPSIS
@@ -226,6 +226,11 @@
 .BI \-report
 Report compression progress.
 .TP
+.BI \-strict
+Treat all warnings as fatal.  Enabling this option will cause the compressor to
+abort if an LZW-compressed GIF input image contains incomplete or corrupt image
+data.
+.TP
 .B \-verbose
 Enable debug printout.  More
 .BR \-v 's
diff --git a/cjpeg.c b/cjpeg.c
index c99a133..b299df6 100644
--- a/cjpeg.c
+++ b/cjpeg.c
@@ -147,6 +147,7 @@
 static char *outfilename;       /* for -outfile switch */
 boolean memdst;                 /* for -memdst switch */
 boolean report;                 /* for -report switch */
+boolean strict;                 /* for -strict switch */
 
 
 #ifdef CJPEG_FUZZER
@@ -240,6 +241,7 @@
   fprintf(stderr, "  -memdst        Compress to memory instead of file (useful for benchmarking)\n");
 #endif
   fprintf(stderr, "  -report        Report compression progress\n");
+  fprintf(stderr, "  -strict        Treat all warnings as fatal\n");
   fprintf(stderr, "  -verbose  or  -debug   Emit debug output\n");
   fprintf(stderr, "  -version       Print version information and exit\n");
   fprintf(stderr, "Switches for wizards:\n");
@@ -285,6 +287,7 @@
   outfilename = NULL;
   memdst = FALSE;
   report = FALSE;
+  strict = FALSE;
   cinfo->err->trace_level = 0;
 
   /* Scan command line options, adjust parameters */
@@ -493,6 +496,9 @@
         usage();
       cinfo->smoothing_factor = val;
 
+    } else if (keymatch(arg, "strict", 2)) {
+      strict = TRUE;
+
     } else if (keymatch(arg, "targa", 1)) {
       /* Input file is Targa format. */
       is_targa = TRUE;
@@ -540,6 +546,19 @@
 }
 
 
+METHODDEF(void)
+my_emit_message(j_common_ptr cinfo, int msg_level)
+{
+  if (msg_level < 0) {
+    /* Treat warning as fatal */
+    cinfo->err->error_exit(cinfo);
+  } else {
+    if (cinfo->err->trace_level >= msg_level)
+      cinfo->err->output_message(cinfo);
+  }
+}
+
+
 /*
  * The main program.
  */
@@ -600,6 +619,9 @@
 
   file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);
 
+  if (strict)
+    jerr.emit_message = my_emit_message;
+
 #ifdef TWO_FILE_COMMANDLINE
   if (!memdst) {
     /* Must have either -outfile switch or explicit output file name */