git: 27bea38852a7 - main - graphics/xv: update for jasper 3 support
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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 ***