Skip to content

Commit

Permalink
Resolve Issue #734: invalid colormap made in jbcorrelation and jbrank…
Browse files Browse the repository at this point in the history
…haus.

* Clarified comments in pixcmapIsValid()
* Bad colormap indices were generated in jbDataRender() by doing bit-or
  between colormap indices.
* Also clean up libversions.c
  • Loading branch information
DanBloomberg committed Feb 18, 2024
1 parent e09c1f2 commit 5e4f9a6
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 48 deletions.
1 change: 1 addition & 0 deletions prog/jbrankhaus.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ PIXA *pixa, *pixadb;
/* Save and write out the result */
data = jbDataSave(classer);
jbDataWrite(rootname, data);
lept_stderr("Number of classes: %d\n", classer->nclass);

/* Render the pages from the classifier data.
* Use debugflag == FALSE to omit outlines of each component. */
Expand Down
24 changes: 12 additions & 12 deletions prog/string_reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,17 +227,17 @@ L_REGPARAMS *rp;
lept_free(str4);

/* String length */
lept_stderr("************************************************\n");
lept_stderr("* This error message is intentional *\n");
lept_stderr("******************************************************\n");
lept_stderr("* This error message is intentional *\n");
n = stringLength("", 0);
lept_stderr("************************************************\n");
lept_stderr("******************************************************\n");
regTestCompareValues(rp, 0.0, (l_float32)n, 0.0); /* 27 */
n = stringLength("", 4);
regTestCompareValues(rp, 0, (l_float32)n, 0.0); /* 28 */
lept_stderr("************************************************\n");
lept_stderr("* This error message is intentional *\n");
lept_stderr("******************************************************\n");
lept_stderr("* This error message is intentional *\n");
n = stringLength("morethan4", 4);
lept_stderr("************************************************\n");
lept_stderr("******************************************************\n");
regTestCompareValues(rp, 4, (l_float32)n, 0.0); /* 29 */

/* String concatenation */
Expand All @@ -248,10 +248,10 @@ L_REGPARAMS *rp;
regTestCompareValues(rp, 3.0, (l_float32)n, 0.0); /* 31 */
n = stringLength(smallbuf, 8);
regTestCompareValues(rp, 6.0, (l_float32)n, 0.0); /* 32 */
lept_stderr("************************************************\n");
lept_stderr("* This error message is intentional *\n");
lept_stderr("******************************************************\n");
lept_stderr("* This error message is intentional *\n");
n = stringCat(smallbuf, 8, "gh");
lept_stderr("************************************************\n");
lept_stderr("******************************************************\n");
regTestCompareValues(rp, -1.0, (l_float32)n, 0.0); /* 33 */
stringCopy(medbuf, smallbuf, 32);
n = stringCat(medbuf, 32, smallbuf);
Expand All @@ -271,10 +271,10 @@ L_REGPARAMS *rp;
n = stringLength(smallbuf, 8);
regTestCompareValues(rp, 6.0, (l_float32)n, 0.0); /* 39 */
stringCopy(smallbuf, medbuf, 8);
lept_stderr("************************************************\n");
lept_stderr("* This error message is intentional *\n");
lept_stderr("******************************************************\n");
lept_stderr("* This error message is intentional *\n");
n = stringLength(smallbuf, 8);
lept_stderr("************************************************\n");
lept_stderr("******************************************************\n");
regTestCompareValues(rp, 8.0, (l_float32)n, 0.0); /* 40 */

return regTestCleanup(rp);
Expand Down
7 changes: 4 additions & 3 deletions src/colormap.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,13 @@ l_int32 d, depth, nalloc, maxindex, maxcolors;

/* Where the colormap or the pix may have been corrupted, and
* in particular when reading or writing image files, it should
* be verified that the image pixel values do not exceed the
* max indexing into the colormap array. */
* be verified that the largest colormap index value in the image
* is less than the number of entries in the colormap array. */
if (pix) {
pixGetMaxColorIndex(pix, &maxindex);
if (maxindex >= cmap->n) {
L_ERROR("(max index = %d) >= (num colors = %d)\n", __func__,
L_ERROR("(max index in image = %d) >= "
"(number entries in colormap = %d)\n", __func__,
maxindex, cmap->n);
return 1;
}
Expand Down
71 changes: 52 additions & 19 deletions src/jbclass.c
Original file line number Diff line number Diff line change
Expand Up @@ -2082,8 +2082,10 @@ jbDataRender(JBDATA *data,
l_int32 i, w, h, cellw, cellh, x, y, iclass, ipage;
l_int32 npages, nclass, ncomp, wp, hp;
BOX *box;
BOXA *boxa;
BOXAA *baa;
NUMA *naclass, *napage;
PIX *pixt, *pixt2, *pix, *pixd;
PIX *pixt, *pix1, *pix2, *pixd;
PIXA *pixat; /* pixa of templates */
PIXA *pixad; /* pixa of output images */
PIXCMAP *cmap;
Expand All @@ -2106,21 +2108,22 @@ PTA *ptaul;

/* Reconstruct the original set of images from the templates
* and the data associated with each component. First,
* generate the output pixa as a set of empty pix. */
* generate the output pixa as a set of empty pix. For debug,
* where the bounding boxes of each component will be displayed
* in red, use 2 bpp colormapped output pix. */
if ((pixad = pixaCreate(npages)) == NULL)
return (PIXA *)ERROR_PTR("pixad not made", __func__, NULL);
for (i = 0; i < npages; i++) {
if (debugflag == FALSE) {
pix = pixCreate(w, h, 1);
pix1 = pixCreate(w, h, 1);
} else {
pix = pixCreate(w, h, 2);
pix1 = pixCreate(w, h, 2);
cmap = pixcmapCreate(2);
pixcmapAddColor(cmap, 255, 255, 255);
pixcmapAddColor(cmap, 0, 0, 0);
pixcmapAddColor(cmap, 255, 0, 0); /* for box outlines */
pixSetColormap(pix, cmap);
pixSetColormap(pix1, cmap);
}
pixaAddPix(pixad, pix, L_INSERT);
pixaAddPix(pixad, pix1, L_INSERT);
}

/* Put the class templates into a pixa. */
Expand All @@ -2129,27 +2132,57 @@ PTA *ptaul;
return (PIXA *)ERROR_PTR("pixat not made", __func__, NULL);
}

/* Place each component in the right location on its page. */
/* Place each component in the right location on its page.
* For debug, first generate the boxa of component bounding
* boxes for each page, and save the results in a boxaa.
* Nota bene. In general we cannot use rasterop on colormap
* indices with operations like PIX_SRC | PIX_DST. So we must
* do the rasterop of image components first, and then paint
* the component bounding boxes later. We can use rasterop
* on the 2 bpp pix here because the colormap has only two
* index values, 0 and 1, * so doing a bit-or between pixels
* only affects the lower-order bit and does not generate
* spurious colormap indices. */
if (debugflag == TRUE) {
baa = boxaaCreate(npages);
boxa = boxaCreate(0);
boxaaInitFull(baa, boxa);
boxaDestroy(&boxa);
}
for (i = 0; i < ncomp; i++) {
numaGetIValue(napage, i, &ipage);
numaGetIValue(naclass, i, &iclass);
pix = pixaGetPix(pixat, iclass, L_CLONE); /* the template */
wp = pixGetWidth(pix);
hp = pixGetHeight(pix);
pix1 = pixaGetPix(pixat, iclass, L_CLONE); /* the template */
wp = pixGetWidth(pix1);
hp = pixGetHeight(pix1);
ptaGetIPt(ptaul, i, &x, &y);
pixd = pixaGetPix(pixad, ipage, L_CLONE); /* the output page */
if (debugflag == FALSE) {
pixRasterop(pixd, x, y, wp, hp, PIX_SRC | PIX_DST, pix, 0, 0);
pixRasterop(pixd, x, y, wp, hp, PIX_SRC | PIX_DST, pix1, 0, 0);
} else {
pixt2 = pixConvert1To2Cmap(pix);
pixRasterop(pixd, x, y, wp, hp, PIX_SRC | PIX_DST, pixt2, 0, 0);
pix2 = pixConvert1To2Cmap(pix1);
pixRasterop(pixd, x, y, wp, hp, PIX_SRC | PIX_DST, pix2, 0, 0);
boxa = boxaaGetBoxa(baa, ipage, L_CLONE);
box = boxCreate(x, y, wp, hp);
pixRenderBoxArb(pixd, box, 1, 255, 0, 0);
pixDestroy(&pixt2);
boxDestroy(&box);
boxaAddBox(boxa, box, L_INSERT);
boxaDestroy(&boxa); /* clone */
pixDestroy(&pix2); /* clone */
}
pixDestroy(&pix1); /* clone */
pixDestroy(&pixd); /* clone */
}

/* For debug, for each page image, render the box outlines in red.
* This adds a red colormap entry to each page. */
if (debugflag == TRUE) {
for (i = 0; i < npages; i++) {
pixd = pixaGetPix(pixad, i, L_CLONE);
boxa = boxaaGetBoxa(baa, i, L_CLONE);
pixRenderBoxaArb(pixd, boxa, 1, 255, 0, 0);
pixDestroy(&pixd); /* clone */
boxaDestroy(&boxa); /* clone */
}
pixDestroy(&pix); /* the clone only */
pixDestroy(&pixd); /* the clone only */
boxaaDestroy(&baa);
}

pixaDestroy(&pixat);
Expand Down
28 changes: 14 additions & 14 deletions src/libversions.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@
#endif

#if HAVE_LIBJP2K
#ifdef LIBJP2K_HEADER
#include LIBJP2K_HEADER
#else
#include <openjpeg.h>
#endif
#ifdef LIBJP2K_HEADER
#include LIBJP2K_HEADER
#else
#include <openjpeg.h>
#endif
#endif


Expand All @@ -88,13 +88,13 @@
* <pre>
* Notes:
* (1) This returns a string of version numbers; e.g.,
* libgif 5.0.3
* libjpeg 8b (libjpeg-turbo 1.3.0)
* libpng 1.4.3
* libtiff 3.9.5
* zlib 1.2.5
* libwebp 0.3.0
* libopenjp2 2.1.0
* libgif 5.1.4
* libjpeg 8b (libjpeg-turbo 2.0.3)
* libpng 1.6.37
* libtiff 4.1.0
* zlib 1.2.11
* libwebp 0.6.1
* libopenjp2 2.5.0
* (2) The caller must free the memory.
* </pre>
*/
Expand Down Expand Up @@ -139,8 +139,8 @@ char *versionStrP = NULL;
/* To stringify the result of expansion of a macro argument,
* you must use two levels of macros. See:
* https://gcc.gnu.org/onlinedocs/cpp/Stringification.html */
#define l_xstr(s) l_str(s)
#define l_str(s) #s
#define l_xstr(s) l_str(s)
#define l_str(s) #s
snprintf(buf, sizeof(buf), " (libjpeg-turbo %s)",
l_xstr(LIBJPEG_TURBO_VERSION));
stringJoinIP(&versionStrP, buf);
Expand Down
1 change: 1 addition & 0 deletions version-notes.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ <h2 align=center> <IMG SRC="moller52.jpg" border=1 ALIGN_MIDDLE> </h2>
removes need for temp file on Windows when writing to/from memory.
* Achieve consistency with fclose() in library and lept_fclose()
in progs. Ditto for lept_free, lept_calloc, lept_fopen(), etc.
* Fix generation of bad colormap indices in jbcorrelation and jbrankhaus
* Source files changed: adaptmap.c gplot.c, grayquant.c, jp2kheader.c,
jp2kheaderstub.c, jp2kio.c, partify.c, pdfio2.c, pixconv.c,
psio2.c, readfile.c, utils2.c, writefile.c, allheaders.h, environ.h
Expand Down

0 comments on commit 5e4f9a6

Please sign in to comment.