diff --git a/src/allheaders.h b/src/allheaders.h index acd28daa6..454e7eb83 100644 --- a/src/allheaders.h +++ b/src/allheaders.h @@ -1550,7 +1550,8 @@ LEPT_DLL extern PIX * pixSubtract ( PIX *pixd, PIX *pixs1, PIX *pixs2 ); LEPT_DLL extern l_int32 pixZero ( PIX *pix, l_int32 *pempty ); LEPT_DLL extern l_int32 pixForegroundFraction ( PIX *pix, l_float32 *pfract ); LEPT_DLL extern NUMA * pixaCountPixels ( PIXA *pixa ); -LEPT_DLL extern l_int32 pixCountPixels ( PIX *pix, l_int32 *pcount, l_int32 *tab8 ); +LEPT_DLL extern l_int32 pixCountPixels ( PIX *pixs, l_int32 *pcount, l_int32 *tab8 ); +LEPT_DLL extern l_int32 pixCountPixelsInRect ( PIX *pixs, BOX *box, l_int32 *pcount, l_int32 *tab8 ); LEPT_DLL extern NUMA * pixCountByRow ( PIX *pix, BOX *box ); LEPT_DLL extern NUMA * pixCountByColumn ( PIX *pix, BOX *box ); LEPT_DLL extern NUMA * pixCountPixelsByRow ( PIX *pix, l_int32 *tab8 ); diff --git a/src/boxfunc1.c b/src/boxfunc1.c index 803c5174f..b2c0a4fde 100644 --- a/src/boxfunc1.c +++ b/src/boxfunc1.c @@ -1206,7 +1206,7 @@ BOX *box; /*! * \brief boxaFindNearestBoxes() * - * \param[in] boxa sorted in LR/TB scan order + * \param[in] boxa either unsorted, or 2D sorted in LR/TB scan order * \param[in] dist_select L_NON_NEGATIVE, L_ALL * \param[in] range search distance from box i; use 0 to search * entire boxa (e.g., if it's not 2D sorted) @@ -1276,7 +1276,7 @@ NUMAA *naai, *naad; /*! * \brief boxaGetNearestByDirection() * - * \param[in] boxa sorted in LR/TB scan order + * \param[in] boxa either unsorted, or 2D sorted in LR/TB scan order * \param[in] i box we test against * \param[in] dir direction to look: L_FROM_LEFT, L_FROM_RIGHT, * L_FROM_TOP, L_FROM_BOT @@ -1344,7 +1344,7 @@ l_int32 x, y, w, h, bx, by, bw, bh; if ((bx >= x && dir == L_FROM_LEFT) || /* not to the left */ (x >= bx && dir == L_FROM_RIGHT)) /* not to the right */ continue; - if (boxHasOverlapInXorY(y, h, by, bh) >= 0) { + if (boxHasOverlapInXorY(y, h, by, bh) == 1) { dist = boxGetDistanceInXorY(x, w, bx, bw); if (dist_select == L_NON_NEGATIVE && dist < 0) continue; if (dist < mindist) { @@ -1360,7 +1360,7 @@ l_int32 x, y, w, h, bx, by, bw, bh; if ((by >= y && dir == L_FROM_TOP) || /* not above */ (y >= by && dir == L_FROM_BOT)) /* not below */ continue; - if (boxHasOverlapInXorY(x, w, bx, bw) >= 0) { + if (boxHasOverlapInXorY(x, w, bx, bw) == 1) { dist = boxGetDistanceInXorY(y, h, by, bh); if (dist_select == L_NON_NEGATIVE && dist < 0) continue; if (dist < mindist) { @@ -1383,7 +1383,7 @@ l_int32 x, y, w, h, bx, by, bw, bh; * \param[in] s1 width or height of box1 * \param[in] c2 left or top coordinate of box2 * \param[in] s2 width or height of box2 - * \return amount of overlap (no overlap if < 0) + * \return 0 if no overlap; 1 if any overlap * *
  * Notes:
@@ -1403,7 +1403,7 @@ l_int32  ovlp;
         ovlp = c2 + s2 - 1 - c1;
     else
         ovlp = c1 + s1 - 1 - c2;
-    return ovlp;
+    return (ovlp < 0) ? 0 : 1;
 }
 
 
@@ -1426,9 +1426,9 @@ boxGetDistanceInXorY(l_int32  c1,
 l_int32  dist;
 
     if (c1 > c2)
-        dist = c1 -c2 - s2 + 1;
+        dist = c1 - (c2 + s2 - 1);
     else
-        dist = c2 - c1 - s1 + 1;
+        dist = c2 - (c1 + s1 - 1);
     return dist;
 }
 
diff --git a/src/pix3.c b/src/pix3.c
index 937e299c0..1cf525da8 100644
--- a/src/pix3.c
+++ b/src/pix3.c
@@ -63,6 +63,7 @@
  *           l_int32     pixForegroundFraction()
  *           NUMA       *pixaCountPixels()
  *           l_int32     pixCountPixels()
+ *           l_int32     pixCountPixelsInRect()
  *           NUMA       *pixCountByRow()
  *           NUMA       *pixCountByColumn()
  *           NUMA       *pixCountPixelsByRow()
@@ -1814,13 +1815,13 @@ PIX      *pix;
 /*!
  * \brief   pixCountPixels()
  *
- * \param[in]    pix 1 bpp
- * \param[out]   pcount count of ON pixels
- * \param[in]    tab8  [optional] 8-bit pixel lookup table
+ * \param[in]    pixs     1 bpp
+ * \param[out]   pcount   count of ON pixels
+ * \param[in]    tab8     [optional] 8-bit pixel lookup table
  * \return  0 if OK; 1 on error
  */
 l_int32
-pixCountPixels(PIX      *pix,
+pixCountPixels(PIX      *pixs,
                l_int32  *pcount,
                l_int32  *tab8)
 {
@@ -1835,13 +1836,13 @@ l_uint32  *data;
     if (!pcount)
         return ERROR_INT("&count not defined", procName, 1);
     *pcount = 0;
-    if (!pix || pixGetDepth(pix) != 1)
-        return ERROR_INT("pix not defined or not 1 bpp", procName, 1);
+    if (!pixs || pixGetDepth(pixs) != 1)
+        return ERROR_INT("pixs not defined or not 1 bpp", procName, 1);
 
     tab = (tab8) ? tab8 : makePixelSumTab8();
-    pixGetDimensions(pix, &w, &h, NULL);
-    wpl = pixGetWpl(pix);
-    data = pixGetData(pix);
+    pixGetDimensions(pixs, &w, &h, NULL);
+    wpl = pixGetWpl(pixs);
+    data = pixGetData(pixs);
     fullwords = w >> 5;
     endbits = w & 31;
     endmask = (endbits == 0) ? 0 : (0xffffffffU << (32 - endbits));
@@ -1874,6 +1875,46 @@ l_uint32  *data;
 }
 
 
+/*!
+ * \brief   pixCountPixelsInRect()
+ *
+ * \param[in]    pixs     1 bpp
+ * \param[in]    box      (can be null)
+ * \param[out]   pcount   count of ON pixels
+ * \param[in]    tab8     [optional] 8-bit pixel lookup table
+ * \return  0 if OK; 1 on error
+ */
+l_int32
+pixCountPixelsInRect(PIX      *pixs,
+                     BOX      *box,
+                     l_int32  *pcount,
+                     l_int32  *tab8)
+{
+l_int32  bx, by, bw, bh;
+PIX     *pix1;
+
+    PROCNAME("pixCountPixelsInRect");
+
+    if (!pcount)
+        return ERROR_INT("&count not defined", procName, 1);
+    *pcount = 0;
+    if (!pixs || pixGetDepth(pixs) != 1)
+        return ERROR_INT("pixs not defined or not 1 bpp", procName, 1);
+
+    if (box) {
+        boxGetGeometry(box, &bx, &by, &bw, &bh);
+        pix1 = pixCreate(bw, bh, 1);
+        pixRasterop(pix1, 0, 0, bw, bh, PIX_SRC, pixs, bx, by);
+        pixCountPixels(pix1, pcount, tab8);
+        pixDestroy(&pix1);
+    } else {
+        pixCountPixels(pixs, pcount, tab8);
+    }
+
+    return 0;
+}
+
+
 /*!
  * \brief   pixCountByRow()
  *