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 ***