git: 27bea38852a7 - main - graphics/xv: update for jasper 3 support

From: Dirk Meyer <dinoex_at_FreeBSD.org>
Date: Wed, 02 Mar 2022 09:57:23 UTC
The branch main has been updated by dinoex:

URL: https://cgit.FreeBSD.org/ports/commit/?id=27bea38852a7e0f5af8cdada0437c349e5d0aa57

commit 27bea38852a7e0f5af8cdada0437c349e5d0aa57
Author:     Dirk Meyer <dinoex@FreeBSD.org>
AuthorDate: 2022-03-02 09:56:56 +0000
Commit:     Dirk Meyer <dinoex@FreeBSD.org>
CommitDate: 2022-03-02 09:56:56 +0000

    graphics/xv: update for jasper 3 support
---
 graphics/xv/Makefile             |    2 +-
 graphics/xv/files/patch-xvjp2k.c | 2382 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 2375 insertions(+), 9 deletions(-)

diff --git a/graphics/xv/Makefile b/graphics/xv/Makefile
index 0bb76fb34381..4998e169a6ed 100644
--- a/graphics/xv/Makefile
+++ b/graphics/xv/Makefile
@@ -2,7 +2,7 @@
 
 PORTNAME=	xv
 PORTVERSION=	3.10a
-PORTREVISION=	17
+PORTREVISION=	18
 CATEGORIES+=	graphics
 MASTER_SITES=	ftp://ftp.cis.upenn.edu/pub/xv/:base \
 		SF/png-mng/XV%20jumbo%20patches/20070520
diff --git a/graphics/xv/files/patch-xvjp2k.c b/graphics/xv/files/patch-xvjp2k.c
index 36e6e70a37e6..2f84d53a8c16 100644
--- a/graphics/xv/files/patch-xvjp2k.c
+++ b/graphics/xv/files/patch-xvjp2k.c
@@ -1,11 +1,2377 @@
---- xvjp2k.c.orig	2007-05-14 01:04:37 UTC
-+++ xvjp2k.c
-@@ -76,7 +76,7 @@ static const char *fbasename,  /* File's base name, fo
- */
- int jas_getdbglevel(void) {return 0;}
- int jas_setdbglevel(int n) {return 0;}
+diff -ur ./xvjp2k.c /home/src/master/GIT/xv/src/xvjp2k.c
+--- ./xvjp2k.c	2022-02-20 20:18:25.590840000 +0100
++++ /home/src/master/GIT/xv/src/xvjp2k.c	2022-02-20 20:39:26.277883000 +0100
+@@ -2,20 +2,20 @@
+  * xvjp2k.c - I/O subroutines for JPEG 2000 format pictures
+  *
+  * This module is a "shim" between XV and a JPEG 2000 CODEC in the open-source
+- * JasPer Library created by Michael D. Adams; for more information, see the URL
+- * "http://www.ece.uvic.ca/~mdadams/jasper".  We don't use most of the other
+- * facilities in this library, so it's better to link XV with a UNIX "archive"
+- * representation of it, not a DLL.
++ * JasPer Library created by Michael D. Adams; for more information, see the
++ * URL "http://www.ece.uvic.ca/~mdadams/jasper".  We don't use most of the
++ * other facilities in this library, so it's better to link XV with a UNIX
++ * "archive" representation of it, not a DLL.
+  *
+  * JPEG 2000 files can be represented in either of two general ways:  The
+  * simplest representation is a "code stream", which often has a ".jpc" file
+  * name suffix and is organized much like a classical JPEG file, except that
+  * unfortunately, JPEG 2000 code streams indicate the no. of colors in an image
+  * but no longer give any clues about its color space (e.g., RGB or YCbCr).
+- * Instead, there is now a semantically higher-level representation, which often
+- * has a ".jp2" file name suffix and encapsulates a "code stream" with (possibly
+- * a lot of) color-space information, optionally including things like ICC
+- * correction tables.
++ * Instead, there is now a semantically higher-level representation, which
++ * often has a ".jp2" file name suffix and encapsulates a "code stream" with
++ * (possibly a lot of) color-space information, optionally including things
++ * like ICC correction tables.
+  *
+  * Compared to the IJG JPEG Library used in file "xvjpeg.c", one must solve
+  * several problems for color images when marrying JasPer to XV.
+@@ -25,9 +25,9 @@
+  * normal "X Windows" display, so we must carefully check a decoded image's
+  * parameters in order to reject anything that we can't handle gracefully.
+  *
+- * 2. JasPer prefers to decode/encode images using color-plane "slices", instead
+- *    of interleaved pixels needed by "X Windows", so we must (de)interleave
+- * copies of the image buffer here.
++ * 2. JasPer prefers to decode/encode images using color-plane "slices",
++ * instead of interleaved pixels needed by "X Windows", so we must
++ * (de)interleave copies of the image buffer here.
+  *
+  * XXX  Things to do:
+  *
+@@ -42,599 +42,419 @@
+  *
+  * --Scott Marovich <marovich@hpl.hp.com>, Hewlett-Packard Laboratories,
+  *   January 2005.
++ *
++ * Michael Aadams <mdadams@ece.uvic.ca>, University of Victoria, January 2022.
++ * The original code needed to be almost entirely rewritten due to its
++ * insistence on bypassing the JasPer library API and violating many
++ * preconditions in the usage of the API (which, of course, caused
++ * many problems as the JasPer library evolved over time).
++ *
+  */
+ #include "copyright.h"
+ 
+-#define  NEEDSARGS
++#define NEEDSARGS
+ #include "xv.h"
+ 
+ #ifdef HAVE_JP2K
+ 
+ #include <jasper/jasper.h>
+-/* missing prototype in 1.701.0, sigh: */
+-jas_stream_t *jas_stream_freopen PARM((const char *, const char *, FILE *));
+ 
+-static const char *fbasename,  /* File's base name, for error/warning msgs */
+-    bad_samp[]   = "%s:  can't read %d-plane %s file!",
+-    fmode[]      = "rb",
+-    full_msg[]   = "%s %s. (%ld bytes)",
+-    jp2_kind[]   = "JP2",
+-    jpc_kind[]   = "JPEG 2000",
+-    load_msg[]   = "Loading %dx%d %s %s (%ld bytes)...",
+-    no_mem[]     = "%s:  can't read %s file - out of memory",
+-    pixel_size[] = "%s:  can't display %d-bit pixels!",
+-    shrt_msg[]   = "%dx%d %s %s. ",
+-    truncated[]  = "%s:  Unexpected end of %s file",
+-    read_err[]   = "%s:  I/O error reading %s file",
+-    bad_dims[]   = "%s:  error in JPEG-2000 header (bad image size)";
++#define GIBI (1024ULL * 1024ULL * 1024ULL)
+ 
+-/* We only want to override the JasPer Library's "jas_eprintf()" subroutine in
+-   order to make it a "wrapper" around XV's own error-reporting subroutine, but
+-   because of the way the former is currently packaged in JasPer Library Version
+-   1.701, we must override everything else packaged in the "jas_debug.o" module
+-   with it, otherwise we get "duplicate definition" messages from the linker.
+-*/
+-int jas_getdbglevel(void) {return 0;}
+-int jas_setdbglevel(int n) {return 0;}
 -int jas_memdump(FILE *fp,void *data,size_t len) {return 0;}
-+int jas_memdump(FILE *fp,const void *data,size_t len) {return 0;}
++static const char *fbasename, /* File's base name, for error/warning msgs */
++	bad_samp[] = "%s:  can't read %d-plane %s file!", fmode[] = "rb",
++	full_msg[] = "%s %s. (%ld bytes)", jp2_kind[] = "JP2",
++	jpc_kind[] = "JPEG 2000", load_msg[] = "Loading %dx%d %s %s (%ld bytes)...",
++	no_mem[] = "%s:  can't read %s file - out of memory",
++	pixel_size[] = "%s:  can't display %d-bit pixels!",
++	shrt_msg[] = "%dx%d %s %s. ",
++	truncated[] = "%s:  Unexpected end of %s file",
++	read_err[] = "%s:  I/O error reading %s file",
++	bad_dims[] = "%s:  error in JPEG-2000 header (bad image size)";
+ 
+-int jas_eprintf(const char *fmt,...)         /* Handle JasPer Library message */
++static int get_debug_level(void)
+ {
+-    static char error[] = "error: ", warning[]= "warning: ";
+-    va_list ap;
+-    int kind = ISTR_WARNING;
+-    char buffer[512];
+-    register char *p;
+-
+- /* Unlike the IJG JPEG Library, the JasPer Library current has no graceful way
+-    for an application (= us!) to intercept its diagnostic messages and output
+-    them using our own subroutines, so this ugly replacement for its output
+-    subroutine will have to suffice.  At Version 1.701, lthough the library's
+-    own "jas_eprintf()" is a varargs subroutine, all calls currently pass just
+-    1 string with a Line Feed at the end and no "printf(3C)" arguments.  Most
+-    strings begin with "error: " or "warning: ", although a few have neither.
+-    We try to translate these into the format preferred by XV, trimming any
+-    trailing Line Feed character (ugh!).
+- */
+-    va_start(ap, fmt);
+-    vsnprintf(p = buffer,512,fmt,ap);
+-    va_end(ap);
+-    while (*p++);
+-    if (p[-2] == '\n') p[-2] = '\0';
+-    p = buffer;
+-    if (strncmp(p,error,sizeof error) == 0) /* "error: ... " */
+-      {
+-        kind = ISTR_WARNING;
+-        p += sizeof error;
+-      }
+-    else /* "warning: ... " */
+-      if (strncmp(p,warning,sizeof warning) == 0)
+-        {
+-          kind = ISTR_INFO;
+-          p += sizeof warning;
+-        };
+-    SetISTR(kind,"%s:  %s",fbasename,p);
+-    return strlen(fmt);
++	int debug_level = 0;
++	const char *cp;
++	if ((cp = getenv("XV_JASPER_DEBUG_LEVEL"))) {
++		debug_level = atoi(cp);
++	}
++	return debug_level;
+ }
+ 
+-static char *SetBuf(FILE *f)
+-{
+-    char *buf;
+-    register char *p;
++#if (JAS_VERSION_MAJOR >= 3)
++static int print_log(jas_logtype_t type, const char *format, va_list ap) {
++	const int buffer_size = 512;
++	char buffer[buffer_size];
++	int count;
+ 
+- /* JPEG 2000 image files are apt to be large, but the buffer size allocated by
+-    most implementations of the "C" Standard I/O Library is still ridiculously
+-    small, typically 1 KB.  We want to allocate a much larger buffer for higher
+-    I/O efficiency, but the details are unfortunately a bit platform-specific.
+-    Under UNIX systems with virtual memory, we want to encourage its internal
+-    "physio()" subroutine by making the buffer an integral number of pages,
+-    aligned on a page-multiple memory address boundary.  Under HP-UX 11.1+ and
+-    perhaps other operating-systems, a Standard I/O buffer is preceded by a
+-    header whose size must also be taken into account.
+- */
+-# ifndef IOBUFSIZ
+-#   define IOBUFSIZ 65536
+-# endif /* IOBUFSIZ */
+-# ifdef __hpux
+-#   define OVERHEAD sizeof(mbstate_t)
+-# endif /* __hpux */
+-# ifndef OVERHEAD
+-#   define OVERHEAD 0
+-# endif /* OVERHEAD */
++	int log_class = jas_logtype_getclass(type);
++	int kind;
++	switch (log_class) {
++	case JAS_LOGTYPE_CLASS_INFO:
++		kind = ISTR_INFO;
++		break;
++	case JAS_LOGTYPE_CLASS_WARN:
++	case JAS_LOGTYPE_CLASS_ERROR:
++	default:
++		kind = ISTR_WARNING;
++		break;
++	}
+ 
+-# ifdef NBPG
+-    if (!(buf = p = malloc(NBPG+OVERHEAD+IOBUFSIZ))) return 0;
+-    p = (char *)((unsigned long)p+NBPG-1 & ~(NBPG-1));
+-    p -= OVERHEAD;
+-# else /* not NBPG */
+-    if (!(buf = p = malloc(OVERHEAD+IOBUFSIZ))) return 0;
+-    p += OVERHEAD;
+-# endif /* NBPG */
+-    setvbuf(f,p,_IOFBF,OVERHEAD+IOBUFSIZ);
+-    return buf;
+-#   undef OVERHEAD
+-#   undef IOBUFSIZ
++	count = vsnprintf(buffer, buffer_size, format, ap);
++
++	if (log_class == JAS_LOGTYPE_CLASS_WARN ||
++		log_class == JAS_LOGTYPE_CLASS_ERROR) {
++		if (get_debug_level() >= 1) {
++			jas_eprintf("%s", buffer);
++		} else {
++			int i;
++			for (i = 0; i < count; ++i) {
++				if (buffer[i] == '\n') {
++					buffer[i] = ' ';
++				}
++			}
++			SetISTR(kind, "%s:  %s", fbasename, buffer);
++		}
++	} else {
++		jas_eprintf("%s", buffer);
++	}
++	return count;
+ }
++#endif
+ 
+-int LoadJPC(char *fname,register PICINFO *pinfo,int quick)
+-{
+-    jas_image_t *img;
+-    jas_stream_t *str;
+-    FILE *fp;
+-    char *iobuf;
+-    const char *s;
+-    unsigned long filesize;
+-    long w, h, npixels, bufsize;
+-    int ok = 0, vstride;
+-    register int i;
++static int LoadJP2K(char *fname, register PICINFO *pinfo, int quick,
++  bool jpc_format) {
++	jas_image_t *img = 0;
++	jas_stream_t *str = 0;
++	FILE *fp;
++	const char *s;
++	unsigned long filesize;
++	long w, h, npixels, bufsize;
++	int vstride;
++	register int i;
++	jas_matrix_t *data = 0;
+ 
+- /* Load a JPEG 2000 "code stream" image file into a pixel buffer for XV.
+-    Unlike classical JPEG files, they have no clue about the image's color
+-    space, so we check for 8-bit data samples but make no effort to check or
+-    convert color spaces, and "what you see is what you get".  For now, ignore
+-    the "quick" option to return a reduced-resolution or -size image.  Return 1
+-    on success, or 0 on failure.
+- */
+-    if (!(fp = xv_fopen(fname,fmode))) return 0;
+-    fbasename = BaseName(fname); /* Input file's base name, for message(s) */
+-    if (!(iobuf = SetBuf(fp)))
+-      {
+-        (void)fclose(fp);
+-        SetISTR(ISTR_WARNING,no_mem,fbasename,jpc_kind);
+-        goto L3;
+-      }
++	int ret = 1;
+ 
+- /* Before telling the JasPer Library about this file, get its size for display
+-    purposes.  Non-UNIX systems don't necessarily simulate "stat(2)", so do it
+-    crudely but portably by seeking to the end, then back to the beginning.
+- */
+-    fseek(fp,0L,2);
+-    filesize = ftell(fp);
+-    fseek(fp,0L,0);
++	int debug_level = get_debug_level();
++#if (JAS_VERSION_MAJOR >= 3)
++	size_t max_mem = jas_get_total_mem_size();
++	if (!max_mem) {
++		max_mem = GIBI;
++	}
++	jas_conf_clear();
++	jas_conf_set_max_mem_usage(max_mem);
++	jas_init_library();
++	jas_init_thread();
++	jas_set_vlogmsgf(print_log);
++#else
++	jas_init();
++#endif
++#if (JAS_VERSION_MAJOR >= 3)
++	jas_set_debug_level(debug_level);
++#else
++	jas_setdbglevel(debug_level);
++#endif
+ 
+- /* "jas_stream_close()" will eventually close the input file, so only do it
+-    explicitly if no stream can be created:
+- */
+-    if (!(str = jas_stream_freopen(fname,fmode,fp))) /* nice if prototype... */
+-      {
+-        (void)fclose(fp);
+-        goto L3;
+-      }
++	if (!(fp = xv_fopen(fname, fmode))) {
++		return 0;
++	}
++	/* Input file's base name, for message(s) */
++	fbasename = BaseName(fname);
+ 
+- /* It's not clear to me whether the following represents a JasPer Library "bug"
+-    but it sure looks goofy:  Unless a stream buffer is marked "read only",
+-    which only happens when the stream's "fillbuf" method is called, even though
+-    our buffers are always "read only", the library will try to flush out buffer
+-    contents when the stream is destroyed, which makes it die a horrible death.
+-    So, mark the stream buffer proactively:
+- */
+-    str->bufmode_ |= JAS_STREAM_RDBUF; /* We will only read the stream buffer */
+-    if (!(img = jpc_decode(str,0))) goto L2;
+-    if ((vstride = jas_image_numcmpts(img))) /* num. color planes */
+-      {
++	/* Compute file size is portable way. */
++	fseek(fp, 0L, 2);
++	filesize = ftell(fp);
++	fseek(fp, 0L, 0);
+ 
+-     /* After the image-component streams created, they are left in a "write"
+-        state with the streams' cursors positioned at their ends, so "seek" in
+-        order to "read" each stream from its beginning.
+-     */
+-        i = vstride;
+-        while (--i >= 0)
+-          if (jas_stream_seek(img->cmpts_[i]->stream_,0L,0))
+-            {
+-              SetISTR(ISTR_WARNING,read_err,fbasename,jpc_kind);
+-              goto L1;
+-            }
+-      }
+-    w = jas_image_width(img);
+-    h = jas_image_height(img);
++#if (JAS_VERSION_MAJOR >= 3)
++	/*
++	This approach will not work in JasPer prior to 3.0.0 due to a bug in
++	the stream code.
++	*/
++	if (!(str = jas_stream_freopen(fname,fmode,fp))) {
++		fclose(fp);
++		ret = 0;
++		goto done;
++	}
+ 
+-    /* avoid buffer overflow */
+-    npixels = w * h;
+-    bufsize = vstride * npixels;
+-    if (w <= 0 || h <= 0 || npixels/w != h || bufsize/vstride != npixels)
+-      {
+-        (void)fclose(fp);
+-        SetISTR(ISTR_WARNING,bad_dims,fbasename);
+-        goto L1;
+-      }
+-    pinfo->normw = pinfo->w = w;
+-    pinfo->normh = pinfo->h = h;
++	/* It's not clear to me whether the following represents a JasPer Library
++	   "bug" but it sure looks goofy:  Unless a stream buffer is marked "read
++	   only", which only happens when the stream's "fillbuf" method is called,
++	   even though our buffers are always "read only", the library will try to
++	   flush out buffer contents when the stream is destroyed, which makes it
++	   die a horrible death. So, mark the stream buffer proactively:
++	*/
++	str->bufmode_ |= JAS_STREAM_RDBUF; /* We will only read the stream buffer */
++#else
++	{
++		if (!(str = jas_stream_memopen(0, 0))) {
++			ret = 0;
++			goto done;
++		}
++		const size_t buffer_size = 1024;
++		char buffer[buffer_size];
++		for (;;) {
++			size_t count;
++			count = fread(buffer, 1, buffer_size, fp);
++			if (!count) {
++				if (!feof(fp)) {
++					ret = 0;
++					goto done;
++				}
++				break;
++			}
++			if (jas_stream_write(str, buffer, count) != count) {
++				ret = 0;
++				goto done;
++			}
++		}
++		jas_stream_rewind(str);
++	}
++#endif
+ 
+- /* Sanity-check the image's color space and no. of colors.  For now, accept
+-    only "generic" color spaces, not files needing image-specific color
+-    correction, but fix that someday...
+- */
+-    switch (vstride)
+-      {
+-        default:
+-          SetISTR(ISTR_WARNING,bad_samp,fbasename,vstride,jpc_kind);
+-          goto L1;
+-        case 1:
+-          if ((i = jas_image_cmptprec(img,0)) != 8) /* not 8-bit pixels */
+-            {
+-              SetISTR(ISTR_WARNING,pixel_size,fbasename,i);
+-              goto L1;
+-            }
+-          s = "Greyscale";
+-          pinfo->type = PIC8;
+-          pinfo->colType = F_GREYSCALE;
+-          i = 256; /* Return fake indexed-color "map" */
+-          while (--i >= 0) pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;
+-          break;
+-        case 3:
++	const jas_image_fmtinfo_t *fmtinfo = jas_image_lookupfmtbyname(
++	  jpc_format ? "jpc" : "jp2");
++	assert(fmtinfo);
++	if (!(img = jas_image_decode(str, fmtinfo->id, 0))) {
++		ret = 0;
++		goto done;
++	}
+ 
+-       /* BEWARE OF KLUDGE:  If the image's color space is RGB, assume that the
+-                             data-sample precision for all color planes is the
+-          same.  If the color space is YCbCr, assume the luminance (Y = 0th)
+-          component has the greatest precision, although the chrominance
+-          (Cr = 1st, Cb = 2nd) components are usually sub-sampled.
+-       */
+-          if ((i = jas_image_cmptprec(img,0)) != 8) /* not 24-bit pixels */
+-            {
+-              SetISTR(ISTR_WARNING,pixel_size,fbasename,i*3);
+-              goto L1;
+-            }
+-          s = "Color";
+-          pinfo->type = PIC24;
+-          pinfo->colType = F_FULLCOLOR;
++	w = jas_image_width(img);
++	h = jas_image_height(img);
++	vstride = jas_image_numcmpts(img);
+ 
+-       /* XXX  Unlike the IJG JPEG Library, the JasPer Library is apparently
+-               unable to quantize colors or tell us whether the image's colors
+-          were quantized by its creator, so it seems that we can't return a
+-          color map for XV to potentially use 8-bit indexed color.  If there
+-          *is* an easy way to do it that escapes me, put the code here someday.
+-       */
+-      }
+-    if (!(pinfo->pic = (byte *)malloc(bufsize))) /* image buffer for XV */
+-      {
+-        SetISTR(ISTR_WARNING,no_mem,fbasename,jpc_kind);
+-        goto L1;
+-      }
+-    pinfo->frmType = F_JPC;
+-    sprintf(pinfo->fullInfo,full_msg,s,jpc_kind,filesize);
+-    sprintf(pinfo->shrtInfo,shrt_msg,pinfo->w,pinfo->h,s,jpc_kind);
+-    SetISTR(ISTR_INFO,load_msg,pinfo->normw,pinfo->normh,s,jpc_kind,filesize);
+-    if (vstride == 1) /* gray-scale image */
+-      { register jas_stream_t *c = img->cmpts_[0]->stream_;
+-        register byte *p = pinfo->pic;
++	/* avoid buffer overflow */
++	npixels = w * h;
++	bufsize = vstride * npixels;
++	if (w <= 0 || h <= 0 || npixels / w != h || bufsize / vstride != npixels) {
++		(void)fclose(fp);
++		SetISTR(ISTR_WARNING, bad_dims, fbasename);
++		ret = 0;
++		goto done;
++	}
++	pinfo->normw = pinfo->w = w;
++	pinfo->normh = pinfo->h = h;
+ 
+-     /* Since this is a 1-plane image, avoid a lot of errant nonsense in the
+-        JasPer Library by sequentially reading all of the data into our buffer
+-        directly.
+-     */
+-        do if ((i = (*c->ops_->read_)(c->obj_,(char *)p,bufsize)) <= 0)
+-             {
+-               SetISTR(ISTR_WARNING,i < 0 ? read_err : truncated,fbasename,
+-                 jpc_kind);
+-               goto L1;
+-             }
+-        while ((p += i),(bufsize -= i) > 0);
+-      }
+-    else /* RGB color image */
+-      {
++	/* Sanity-check the image's color space and no. of colors.  For now, accept
++	   only "generic" color spaces, not files needing image-specific color
++	   correction, but fix that someday...
++	*/
++	switch (vstride) {
++		static char color_space[] = {"%s:  invalid color space!"};
+ 
+-     /* Reading color images is inefficient because JPEG 2000 wants to partition
+-        file data into separate image planes (colors), while XV wants data
+-        samples from each plane to be interleaved as 3-byte pixels.  Apparently
+-        the fastest method consists of 3 passes through the XV image buffer,
+-        into which we insert the bytes of each component.
+-     */
+-        i = 0;
+-        do /* each color component */
+-          { long npix = npixels;
+-            register jas_stream_t *c = img->cmpts_[i]->stream_;
+-            register byte *p = pinfo->pic + i;
++	default:
++		SetISTR(ISTR_WARNING, bad_samp, fbasename, vstride, jp2_kind);
++		ret = 0;
++		goto done;
++	case 1:
++		if (!jas_clrspc_isunknown(i = jas_image_clrspc(img)) &&
++			jas_clrspc_fam(i) != JAS_CLRSPC_FAM_GRAY) {
++			SetISTR(ISTR_WARNING, color_space, fbasename);
++			ret = 0;
++			goto done;
++		}
++		if ((i = jas_image_cmptprec(img, 0)) != 8) /* not 8-bit pixels */
++		{
++			SetISTR(ISTR_WARNING, pixel_size, fbasename, i);
++			ret = 0;
++			goto done;
++		}
++		s = "Greyscale";
++		pinfo->type = PIC8;
++		pinfo->colType = F_GREYSCALE;
++		i = 256; /* Return fake indexed-color "map" */
++		while (--i >= 0)
++			pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;
++		break;
++	case 3:
++		if (jas_clrspc_isunknown(i = jas_image_clrspc(img))) {
++			SetISTR(ISTR_WARNING, color_space, fbasename);
++			ret = 0;
++			goto done;
++		}
++		if (jas_clrspc_fam(i) != JAS_CLRSPC_FAM_RGB) {
++			jas_image_t *oimg;
++			jas_cmprof_t *profile;
+ 
+-            do /* each pixel */
+-              { register int b;
++			/* Here's where the JasPer Library really shines.  The only color
++			   space that XV handles is RGB, so if that's not what our image
++			   uses, then to quote Capt. Kirk:  "Make it so!"
++			*/
++			if (!(profile = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) {
++				SetISTR(ISTR_WARNING, "%s:  can't create RGB profile",
++						fbasename);
++				ret = 0;
++				goto done;
++			}
++			img =
++				jas_image_chclrspc(oimg = img, profile, JAS_CMXFORM_INTENT_PER);
++			jas_cmprof_destroy(profile);
++			if (!img) /* Oops!  We failed, so restore original image */
++			{
++				img = oimg;
++				SetISTR(ISTR_WARNING, "%s:  can't convert to RGB", fbasename);
++				ret = 0;
++				goto done;
++			}
++			jas_image_destroy(oimg);
++		}
+ 
+-                if ((b = jas_stream_getc(c)) < 0)
+-                  {
+-                    SetISTR(ISTR_WARNING,
+-                      (c->flags_ & JAS_STREAM_EOF) ? truncated : read_err,
+-                      fbasename,jpc_kind);
+-                    goto L1;
+-                  }
+-                *p = b;
+-              }
+-            while ((p += 3),--npix > 0);
+-          }
+-        while (++i <= 2);
+-      }
+-    ok = 1; /* Success! */
+-L1: jas_image_destroy(img);
+-L2: (void)jas_stream_close(str);
+-    free(iobuf);
+-L3: return ok;
+-}
++		/* BEWARE OF KLUDGE:  If the image's color space is RGB, assume that the
++							  data-sample precision for all color planes is the
++		   same.  If the color space is YCbCr, assume the luminance (Y = 0th)
++		   component has the greatest precision, although the chrominance
++		   (Cr = 1st, Cb = 2nd) components are usually sub-sampled.
++		*/
++		if ((i = jas_image_cmptprec(img, 0)) != 8) /* not 24-bit pixels */
++		{
++			SetISTR(ISTR_WARNING, pixel_size, fbasename, i * 3);
++			ret = 0;
++			goto done;
++		}
++		s = "Color";
++		pinfo->type = PIC24;
++		pinfo->colType = F_FULLCOLOR;
+ 
+-int LoadJP2(char *fname,register PICINFO *pinfo,int quick)
+-{
+-    jas_image_t *img;
+-    jas_stream_t *str;
+-    FILE *fp;
+-    char *iobuf;
+-    const char *s;
+-    unsigned long filesize;
+-    long w, h, npixels, bufsize;
+-    int ok = 0, vstride;
+-    register int i;
++		/* XXX  Unlike the IJG JPEG Library, the JasPer Library is apparently
++				unable to quantize colors or tell us whether the image's colors
++		   were quantized by its creator, so it seems that we can't return a
++		   color map for XV to potentially use 8-bit indexed color.  If there
++		   *is* an easy way to do it that escapes me, put the code here someday.
++		*/
++	}
+ 
+- /* Load a JPEG 2000 JP2 image file into a pixel buffer for XV, doing any
+-    necessary color-space conversion to end up with 8-bit gray scale or 24-bit
+-    RGB.  For now, ignore the "quick" option to return a reduced-resolution
+-    or -size image.  Return 1 on success, or 0 on failure.
+- */
+-    if (!(fp = xv_fopen(fname,fmode))) return 0;
+-    fbasename = BaseName(fname); /* Input file's base name, for message(s) */
+-    if (!(iobuf = SetBuf(fp)))
+-      {
+-        (void)fclose(fp);
+-        SetISTR(ISTR_WARNING,no_mem,fbasename,jpc_kind);
+-        goto L3;
+-      }
++	/* image buffer for XV */
++	if (!(pinfo->pic = (byte *)malloc(bufsize)))
++	{
++		SetISTR(ISTR_WARNING, no_mem, fbasename, jp2_kind);
++		ret = 0;
++		goto done;
++	}
++	pinfo->frmType = F_JP2;
++	sprintf(pinfo->fullInfo, full_msg, s, jp2_kind, filesize);
++	sprintf(pinfo->shrtInfo, shrt_msg, pinfo->w, pinfo->h, s, jp2_kind);
++	SetISTR(ISTR_INFO, load_msg, pinfo->normw, pinfo->normh, s, jp2_kind,
++			filesize);
+ 
+- /* Before telling the JasPer Library about this file, get its size for display
+-    purposes.  Non-UNIX systems don't necessarily simulate "stat(2)", so do it
+-    crudely but portably by seeking to the end, then back to the beginning.
+- */
+-    fseek(fp,0L,2);
+-    filesize = ftell(fp);
+-    fseek(fp,0L,0);
++	/* Copy the sample data from the JasPer image to the xv image. */
++	{
++		int num_comps = vstride;
++		int width = w;
++		int height = h;
++		int comp_ind;
++		data = jas_matrix_create(height, width);
++		assert(data);
++		for (comp_ind = 0; comp_ind < num_comps; ++comp_ind) {
++			if (jas_image_readcmpt(img, comp_ind, 0, 0, width, height, data)) {
++				ret = 0;
++				goto done;
++			}
++			unsigned char *buffer;
++			jas_seqent_t *src;
++			unsigned char *dst;
++			int xx, yy;
++			dst = pinfo->pic + comp_ind;
++			for (yy = 0; yy < height; ++yy) {
++				src = jas_matrix_getvref(data, yy);
++				for (xx = 0; xx < width; ++xx) {
++					*dst = *src;
++					++src;
++					dst += num_comps;
++				}
++			}
++		}
++	}
+ 
+- /* "jas_stream_close()" will eventually close the input file, so only do it
+-    explicitly if no stream can be created:
+- */
+-    if (!(str = jas_stream_freopen(fname,fmode,fp)))
+-      {
+-        (void)fclose(fp);
+-        goto L3;
+-      }
++	/* Success! */
++	ret = 1;
+ 
+- /* It's not clear to me whether the following represents a JasPer Library "bug"
+-    but it sure looks goofy:  Unless a stream buffer is marked "read only",
+-    which only happens when the stream's "fillbuf" method is called, even though
+-    our buffers are always "read only", the library will try to flush out buffer
+-    contents when the stream is destroyed, which makes it die a horrible death.
+-    So, mark the stream buffer proactively:
+- */
+-    str->bufmode_ |= JAS_STREAM_RDBUF; /* We will only read the stream buffer */
+-    if (!(img = jp2_decode(str,0))) goto L2;
+-    if ((vstride = jas_image_numcmpts(img))) /* num. color planes */
+-      {
++done:
++	if (data) {
++		jas_matrix_destroy(data);
++	}
++	if (img) {
++		jas_image_destroy(img);
++	}
++	if (str) {
++		jas_stream_close(str);
++	}
++#if (JAS_VERSION_MAJOR >= 3)
++	jas_cleanup_thread();
++	jas_cleanup_library();
++#else
++	jas_cleanup();
++#endif
++	return ret;
++}
+ 
+-     /* After the image-component streams created, they are left in a "write"
+-        state with the streams' cursors positioned at their ends, so "seek" in
+-        order to "read" each stream from its beginning.
+-     */
+-        i = vstride;
+-        while (--i >= 0)
+-          if (jas_stream_seek(img->cmpts_[i]->stream_,0L,0))
+-            {
+-              SetISTR(ISTR_WARNING,read_err,fbasename,jp2_kind);
+-              goto L1;
+-            }
+-      }
+-    w = jas_image_width(img);
+-    h = jas_image_height(img);
++int LoadJP2(char *fname, register PICINFO *pinfo, int quick) {
++	return LoadJP2K(fname, pinfo, quick, false);
++}
+ 
+-    /* avoid buffer overflow */
+-    npixels = w * h;
+-    bufsize = vstride * npixels;
+-    if (w <= 0 || h <= 0 || npixels/w != h || bufsize/vstride != npixels)
+-      {
+-        (void)fclose(fp);
+-        SetISTR(ISTR_WARNING,bad_dims,fbasename);
+-        goto L1;
+-      }
+-    pinfo->normw = pinfo->w = w;
+-    pinfo->normh = pinfo->h = h;
+-
+- /* Sanity-check the image's color space and no. of colors.  For now, accept
+-    only "generic" color spaces, not files needing image-specific color
+-    correction, but fix that someday...
+- */
+-    switch (vstride)
+-      { static char color_space[]={"%s:  invalid color space!"};
+-
+-        default:
+-          SetISTR(ISTR_WARNING,bad_samp,fbasename,vstride,jp2_kind);
+-          goto L1;
+-        case 1:
+-          if (   !jas_clrspc_isunknown(i = jas_image_clrspc(img))
+-              && jas_clrspc_fam(i) != JAS_CLRSPC_FAM_GRAY
+-             )
+-            {
+-              SetISTR(ISTR_WARNING,color_space,fbasename);
+-              goto L1;
+-            }
+-          if ((i = jas_image_cmptprec(img,0)) != 8) /* not 8-bit pixels */
+-            {
+-              SetISTR(ISTR_WARNING,pixel_size,fbasename,i);
+-              goto L1;
+-            }
+-          s = "Greyscale";
+-          pinfo->type = PIC8;
+-          pinfo->colType = F_GREYSCALE;
+-          i = 256; /* Return fake indexed-color "map" */
+-          while (--i >= 0) pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;
+-          break;
+-        case 3:
+-          if (jas_clrspc_isunknown(i = jas_image_clrspc(img)))
+-            {
+-              SetISTR(ISTR_WARNING,color_space,fbasename);
+-              goto L1;
+-            }
+-          if (jas_clrspc_fam(i) != JAS_CLRSPC_FAM_RGB)
+-            { jas_image_t *oimg;
+-              jas_cmprof_t *profile;
+-
+-           /* Here's where the JasPer Library really shines.  The only color
+-              space that XV handles is RGB, so if that's not what our image
+-              uses, then to quote Capt. Kirk:  "Make it so!"
+-           */
+-              if (!(profile = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB)))
+-                 {
+-                   SetISTR(ISTR_WARNING,"%s:  can't create RGB profile",
+-                     fbasename);
+-                   goto L1;
+-                 }
+-              img = jas_image_chclrspc( oimg = img
+-                                      , profile
+-                                      , JAS_CMXFORM_INTENT_PER
+-                                      );
+-              jas_cmprof_destroy(profile);
+-              if (!img) /* Oops!  We failed, so restore original image */
+-                {
+-                  img = oimg;
+-                  SetISTR(ISTR_WARNING,"%s:  can't convert to RGB",fbasename);
+-                  goto L1;
+-                }
+-              jas_image_destroy(oimg);
+-            }
+-
+-       /* BEWARE OF KLUDGE:  If the image's color space is RGB, assume that the
+-                             data-sample precision for all color planes is the
+-          same.  If the color space is YCbCr, assume the luminance (Y = 0th)
+-          component has the greatest precision, although the chrominance
+-          (Cr = 1st, Cb = 2nd) components are usually sub-sampled.
+-       */
+-          if ((i = jas_image_cmptprec(img,0)) != 8) /* not 24-bit pixels */
+-            {
+-              SetISTR(ISTR_WARNING,pixel_size,fbasename,i*3);
+-              goto L1;
+-            }
+-          s = "Color";
+-          pinfo->type = PIC24;
+-          pinfo->colType = F_FULLCOLOR;
+-
+-       /* XXX  Unlike the IJG JPEG Library, the JasPer Library is apparently
+-               unable to quantize colors or tell us whether the image's colors
+-          were quantized by its creator, so it seems that we can't return a
+-          color map for XV to potentially use 8-bit indexed color.  If there
+-          *is* an easy way to do it that escapes me, put the code here someday.
+-       */
+-      }
+-    if (!(pinfo->pic = (byte *)malloc(bufsize))) /* image buffer for XV */
+-      {
+-        SetISTR(ISTR_WARNING,no_mem,fbasename,jp2_kind);
+-        goto L1;
+-      }
+-    pinfo->frmType = F_JP2;
+-    sprintf(pinfo->fullInfo,full_msg,s,jp2_kind,filesize);
+-    sprintf(pinfo->shrtInfo,shrt_msg,pinfo->w,pinfo->h,s,jp2_kind);
+-    SetISTR(ISTR_INFO,load_msg,pinfo->normw,pinfo->normh,s,jp2_kind,filesize);
+-    if (vstride == 1) /* gray-scale image */
+-      { register jas_stream_t *c = img->cmpts_[0]->stream_;
+-        register byte *p = pinfo->pic;
+-
+-     /* Since this is a 1-plane image, avoid a lot of errant nonsense in the
+-        JasPer Library by sequentially reading all of the data into our buffer
+-        directly.
+-     */
+-        do if ((i = (*c->ops_->read_)(c->obj_,(char *)p,bufsize)) <= 0)
+-             {
+-               SetISTR(ISTR_WARNING,i < 0 ? read_err : truncated,fbasename,
+-                 jp2_kind);
+-               goto L1;
+-             }
+-        while ((p += i),(bufsize -= i) > 0);
+-      }
+-    else /* RGB color image */
+-      {
+-
+-     /* Reading color images is inefficient because JPEG 2000 wants to partition
+-        file data into separate image planes (colors), while XV wants data
+-        samples from each plane to be interleaved as 3-byte pixels.  Apparently
+-        the fastest method consists of 3 passes through the XV image buffer,
+-        into which we insert the bytes of each component.
+-     */
+-        i = 0;
+-        do /* each color component */
+-          { long npix = npixels;
+-            register jas_stream_t *c = img->cmpts_[i]->stream_;
+-            register byte *p = pinfo->pic + i;
+-
+-            do /* each pixel */
+-              { register int b;
+-
+-                if ((b = jas_stream_getc(c)) < 0)
+-                  {
+-                    SetISTR(ISTR_WARNING,
+-                      (c->flags_ & JAS_STREAM_EOF) ? truncated : read_err,
+-                      fbasename,jp2_kind);
+-                    goto L1;
+-                  }
+-                *p = b;
+-              }
+-            while ((p += 3),--npix > 0);
+-          }
+-        while (++i <= 2);
+-      }
+-    ok = 1; /* Success! */
+-L1: jas_image_destroy(img);
+-L2: (void)jas_stream_close(str);
+-    free(iobuf);
+-L3: return ok;
++int LoadJPC(char *fname, register PICINFO *pinfo, int quick) {
++	return LoadJP2K(fname, pinfo, quick, true);
+ }
+ 
+ /* The following variables and subroutines are used when writing a JPEG 2000
+    file, which is done mainly using call-backs from "X Windows" widgets.  The
+    most complicated part of this interface is: managing interactions with a
+-   window to request the boat-loads of options that the JasPer Library supports.
+-   Start by defining subwindow sizes, plus indices into several arrays of
+-   corresponding widget-state variables.
++   window to request the boat-loads of options that the JasPer Library
++   supports. Start by defining subwindow sizes, plus indices into several
++   arrays of corresponding widget-state variables.
+ 
+    IMPLEMENTATION NOTES:  The following dimensions create a tall, thin window
+-                          which appears to have considerable empty space at the
++						  which appears to have considerable empty space at the
+    bottom.  Before you complain, click the Precinct Height menu button in order
+-   to the tall pop-up subwindow that it generates.  If the parent window is made
+-   shorter, then this pop-up will be clipped, which is an ugly nuisance.  I
++   to the tall pop-up subwindow that it generates.  If the parent window is
++   made shorter, then this pop-up will be clipped, which is an ugly nuisance. I
+    don't know how to make the pop-up visible outside its parent's borders; do
+-   you?  If there's some way to make "X Windows" do this, then we might consider
+-   making the parent shorter.
++   you?  If there's some way to make "X Windows" do this, then we might
++   consider making the parent shorter.
+ 
+    Note that there is currently no mechanism to program the no. of intermediate
+    layers used by the encoder, or their rates.  This is potentially a large and
+    complicated data-entry problem, and perhaps someday we can invent a clever
+    solution using the rest of the parent window's space.
+ */
+-# define JP2KW 275 /* Window width, in pixels */
+-# define JP2KH 400 /* Window height, in pixels */
+-# define BUTTW 51 /* Button width, in pixels (odd for half-toning) */
+-# define BUTTH 20 /* Button height, in pixels */
+-# define MENUW 75 /* Menu-button width, in pixels (odd for half-toning) */
+-# define MENUH 24 /* Menu-button height, in pixels */
+-# define RBUTH 20 /* Radio button height, in pixels */
+-# define RBUTW 51 /* Radio button width, in pixels (odd for half-toning) */
+-# define TEXTH (LINEHIGH+5) /* Text subwindow height, in pixels */
+-# define TEXTW 75 /* Text subwindow width, in pixels */
++#define JP2KW 275 /* Window width, in pixels */
++#define JP2KH 400 /* Window height, in pixels */
++#define BUTTW 51  /* Button width, in pixels (odd for half-toning) */
++#define BUTTH 20  /* Button height, in pixels */
++#define MENUW 75  /* Menu-button width, in pixels (odd for half-toning) */
++#define MENUH 24  /* Menu-button height, in pixels */
*** 1432 LINES SKIPPED ***