diff --git a/src/adaptmap.c b/src/adaptmap.c index e233358ca..46224960d 100644 --- a/src/adaptmap.c +++ b/src/adaptmap.c @@ -144,13 +144,13 @@ * shrinking the dynamic range * (3) results should otherwise not be sensitive to these values */ -static const l_int32 DEFAULT_TILE_WIDTH = 10; /*!< pixBackgroundNormSimple() default tile width */ -static const l_int32 DEFAULT_TILE_HEIGHT = 15; /*!< pixBackgroundNormSimple() default tile height */ -static const l_int32 DEFAULT_FG_THRESHOLD = 60; /*!< pixBackgroundNormSimple() default fg threshold */ -static const l_int32 DEFAULT_MIN_COUNT = 40; /*!< pixBackgroundNormSimple() default minimum count */ -static const l_int32 DEFAULT_BG_VAL = 200; /*!< pixBackgroundNormSimple() default bg value */ -static const l_int32 DEFAULT_X_SMOOTH_SIZE = 2; /*!< pixBackgroundNormSimple() default x smooth size */ -static const l_int32 DEFAULT_Y_SMOOTH_SIZE = 1; /*!< pixBackgroundNormSimple() default y smooth size */ +static const l_int32 DEFAULT_TILE_WIDTH = 10; /*!< default tile width */ +static const l_int32 DEFAULT_TILE_HEIGHT = 15; /*!< default tile height */ +static const l_int32 DEFAULT_FG_THRESHOLD = 60; /*!< default fg threshold */ +static const l_int32 DEFAULT_MIN_COUNT = 40; /*!< default minimum count */ +static const l_int32 DEFAULT_BG_VAL = 200; /*!< default bg value */ +static const l_int32 DEFAULT_X_SMOOTH_SIZE = 2; /*!< default x smooth size */ +static const l_int32 DEFAULT_Y_SMOOTH_SIZE = 1; /*!< default y smooth size */ static l_int32 *iaaGetLinearTRC(l_int32 **iaa, l_int32 diff); diff --git a/src/affine.c b/src/affine.c index 1e253c9a3..58cd6d7d5 100644 --- a/src/affine.c +++ b/src/affine.c @@ -1528,7 +1528,8 @@ PIX *pixt1, *pixt2, *pixd; * src points from the axes to the actual dest position. * These values are also needed to scale the image. */ th3p = atan2((l_float64)(x1p - x3p), (l_float64)(y1p - y3p)); - x2sp = (l_float32)(x2p - ((l_float32)(y1p - y2p) * (x3p - x1p)) / (y1p - y3p)); + x2sp = (l_float32)(x2p - + ((l_float32)(y1p - y2p) * (x3p - x1p)) / (y1p - y3p)); if (x2sp == (l_float32)x1p) return (PIX *)ERROR_PTR("x2sp == x1p!", procName, NULL); ph2p = atan2((l_float64)(y1p - y2p), (l_float64)(x2sp - x1p)); diff --git a/src/affinecompose.c b/src/affinecompose.c index 9ac18af67..6c92d0321 100644 --- a/src/affinecompose.c +++ b/src/affinecompose.c @@ -69,8 +69,9 @@ * \param[in] transy y component of translation wrt. the origin * \return 3x3 transform matrix, or NULL on error * - * Notes; - * 1 The translation is equivalent to: + *
+ * Notes: + * (1) The translation is equivalent to: * v' = Av * where v and v' are 1x3 column vectors in the form * v = [x, y, 1]^ ^ denotes transpose @@ -79,10 +80,11 @@ * 0 1 ty * 0 0 1 ] * - * 2 We consider translation as with respect to a fixed origin. + * (2) We consider translation as with respect to a fixed origin. * In a clipping operation, the origin moves and the points - * are fixed, and you use -tx, -ty) where (tx, ty is the + * are fixed, and you use (-tx, -ty) where (tx, ty) is the * translation vector of the origin. + **/ l_float32 * createMatrix2dTranslate(l_float32 transx, @@ -109,19 +111,21 @@ l_float32 *mat; * \param[in] scaley vertical scale factor * \return 3x3 transform matrix, or NULL on error * - * Notes; - * 1 The scaling is equivalent to: + *
+ * Notes: + * (1) The scaling is equivalent to: * v' = Av - * where v and v' are 1x3 column vectors in the form - * v = [x, y, 1]^ ^ denotes transpose - * and the affine scaling matrix is + * where v and v' are 1x3 column vectors in the form + * v = [x, y, 1]^ ^ denotes transpose + * and the affine scaling matrix is * A = [ sx 0 0 * 0 sy 0 * 0 0 1 ] * - * 2 We consider scaling as with respect to a fixed origin. + * (2) We consider scaling as with respect to a fixed origin. * In other words, the origin is the only point that doesn't * move in the scaling transform. + **/ l_float32 * createMatrix2dScale(l_float32 scalex, @@ -148,8 +152,9 @@ l_float32 *mat; * \param[in] angle rotation in radians; clockwise is positive * \return 3x3 transform matrix, or NULL on error * - * Notes; - * 1 The rotation is equivalent to: + *
+ * Notes: + * (1) The rotation is equivalent to: * v' = Av * where v and v' are 1x3 column vectors in the form * v = [x, y, 1]^ ^ denotes transpose @@ -166,13 +171,14 @@ l_float32 *mat; * * These relations follow from the following equations, which * you can convince yourself are correct as follows. Draw a - * circle centered on xc,yc) and passing through (x,y, with - * x',y') on the arc at an angle 'a' clockwise from (x,y. - * [ Hint: cosa + b = cosa * cosb - sina * sinb - * sina + b = sina * cosb + cosa * sinb ] + * circle centered on xc,yc) and passing through (x,y), with + * (x',y') on the arc at an angle 'a' clockwise from (x,y). + * [ Hint: cosa + b = cosa * cosb - sina * sinb + * sina + b = sina * cosb + cosa * sinb ] * * x' - xc = x - xc) * cosa - (y - yc * sina * y' - yc = x - xc) * sina + (y - yc * cosa + **/ l_float32 * createMatrix2dRotate(l_float32 xc, @@ -211,8 +217,10 @@ l_float32 *mat; * \param[in] transy y component of translation wrt. the origin * \return ptad translated points, or NULL on error * - * Notes; - * 1) See createMatrix2dTranslate( for details of transform. + *
+ * Notes: + * (1) See createMatrix2dTranslate() for details of transform. + **/ PTA * ptaTranslate(PTA *ptas, @@ -248,8 +256,10 @@ PTA *ptad; * \param[in] scaley vertical scale factor * \return 0 if OK; 1 on error * - * Notes; - * 1) See createMatrix2dScale( for details of transform. + *
+ * Notes: + * (1) See createMatrix2dScale() for details of transform. + **/ PTA * ptaScale(PTA *ptas, @@ -285,20 +295,22 @@ PTA *ptad; * \param[in] angle rotation in radians; clockwise is positive * \return 0 if OK; 1 on error * - * Notes; - * 1) See createMatrix2dScale( for details of transform. - * 2 This transform can be thought of as composed of the + *
+ * Notes; + * (1) See createMatrix2dScale() for details of transform. + * (2) This transform can be thought of as composed of the * sum of two parts: - * a) an (x,y-dependent rotation about the origin: + * a) an (x,y)-dependent rotation about the origin: * xr = x * cosa - y * sina * yr = x * sina + y * cosa - * b) an (x,y-independent translation that depends on the + * b) an (x,y)-independent translation that depends on the * rotation center and the angle: * xt = xc - xc * cosa + yc * sina * yt = yc - xc * sina - yc * cosa - * The translation part xt,yt is equal to the difference - * between the center xc,yc and the location of the + * The translation part (xt,yt) is equal to the difference + * between the center (xc,yc) and the location of the * center after it is rotated about the origin. + **/ PTA * ptaRotate(PTA *ptas, @@ -342,8 +354,8 @@ PTA *ptad; * \param[in] transy y component of translation wrt. the origin * \return boxad translated boxas, or NULL on error * - * Notes; - * 1) See createMatrix2dTranslate( for details of transform. + * Notes: + * (1) See createMatrix2dTranslate() for details of transform. */ BOXA * boxaTranslate(BOXA *boxas, @@ -375,8 +387,8 @@ BOXA *boxad; * \param[in] scaley vertical scale factor * \return boxad scaled boxas, or NULL on error * - * Notes; - * 1) See createMatrix2dScale( for details of transform. + * Notes: + * (1) See createMatrix2dScale() for details of transform. */ BOXA * boxaScale(BOXA *boxas, @@ -408,8 +420,8 @@ BOXA *boxad; * \param[in] angle rotation in radians; clockwise is positive * \return boxad scaled boxas, or NULL on error * - * Notes; - * 1) See createMatrix2dRotate( for details of transform. + * Notes: + * (1) See createMatrix2dRotate() for details of transform. */ BOXA * boxaRotate(BOXA *boxas, diff --git a/src/bilinear.c b/src/bilinear.c index 2077c11cd..69eca74e2 100644 --- a/src/bilinear.c +++ b/src/bilinear.c @@ -726,9 +726,10 @@ PTA *ptad2, *ptas2; * \param[out] pvc vector of coefficients of transform * \return 0 if OK; 1 on error * - * We have a set of 8 equations, describing the bilinear - * transformation that takes 4 points ptas into 4 other - * points ptad. These equations are: + *
+ * We have a set of 8 equations, describing the bilinear + * transformation that takes 4 points ptas into 4 other + * points ptad. These equations are: * * x1' = c[0]*x1 + c[1]*y1 + c[2]*x1*y1 + c[3] * y1' = c[4]*x1 + c[5]*y1 + c[6]*x1*y1 + c[7] @@ -739,16 +740,16 @@ PTA *ptad2, *ptas2; * x4' = c[0]*x4 + c[1]*y4 + c[2]*x4*y4 + c[3] * y4' = c[4]*x4 + c[5]*y4 + c[6]*x4*y4 + c[7] * - * This can be represented as + * This can be represented as * * AC = B * - * where B and C are column vectors + * where B and C are column vectors * * B = [ x1' y1' x2' y2' x3' y3' x4' y4' ] * C = [ c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] ] * - * and A is the 8x8 matrix + * and A is the 8x8 matrix * * x1 y1 x1*y1 1 0 0 0 0 * 0 0 0 0 x1 y1 x1*y1 1 @@ -759,16 +760,17 @@ PTA *ptad2, *ptas2; * x4 y4 x4*y4 1 0 0 0 0 * 0 0 0 0 x4 y4 x4*y4 1 * - * These eight equations are solved here for the coefficients C. + * These eight equations are solved here for the coefficients C. * - * These eight coefficients can then be used to find the mapping - * x,y) --> (x',y': + * These eight coefficients can then be used to find the mapping + * x,y) --> (x',y': * * x' = c[0]x + c[1]y + c[2]xy + c[3] * y' = c[4]x + c[5]y + c[6]xy + c[7] * - * that are implemented in bilinearXformSampledPt and - * bilinearXFormPt. + * that are implemented in bilinearXformSampledPt and + * bilinearXFormPt. + **/ l_int32 getBilinearXformCoeffs(PTA *ptas, diff --git a/src/ccbord.c b/src/ccbord.c index a6206e60b..3c7a04b8d 100644 --- a/src/ccbord.c +++ b/src/ccbord.c @@ -2268,8 +2268,8 @@ PTA *pta; pta = ccb->start; for (j = 0; j < nb; j++) { ptaGetIPt(pta, j, &startx, &starty); - bbufferRead(bbuf, (l_uint8 *)&startx, 4); /* starting x in border */ - bbufferRead(bbuf, (l_uint8 *)&starty, 4); /* starting y in border */ + bbufferRead(bbuf, (l_uint8 *)&startx, 4); /* starting x in border */ + bbufferRead(bbuf, (l_uint8 *)&starty, 4); /* starting y in border */ na = numaaGetNuma(naa, j, L_CLONE); n = numaGetCount(na); for (k = 0; k < n; k++) { @@ -2279,7 +2279,7 @@ PTA *pta; else bval |= (l_uint8)val; if (k % 2 == 1) - bbufferRead(bbuf, (l_uint8 *)&bval, 1); /* 2 border steps */ + bbufferRead(bbuf, (l_uint8 *)&bval, 1); /* 2 border steps */ } if (n % 2 == 1) { bval |= 0x8; @@ -2340,6 +2340,7 @@ CCBORDA *ccba; * \param[in] fp file stream * \return ccba, or NULL on error * + * \code * Format: ccba: %7d cc\n num. c.c.) (ascii) (17B * pix width 4B * pix height 4B @@ -2355,6 +2356,7 @@ CCBORDA *ccba; * [for k = 1, nb] * 2 steps 1B * end in z8 or 88 1B + * \endcode */ CCBORDA * ccbaReadStream(FILE *fp) diff --git a/src/classapp.c b/src/classapp.c index 90abab562..63532ec25 100644 --- a/src/classapp.c +++ b/src/classapp.c @@ -52,9 +52,9 @@ #include
+ * This data structure is used for pixOctreeColorQuant(), + * a color octree that adjusts to the color distribution + * in the image that is being quantized. The best settings + * are with CQ_NLEVELS = 6 and DITHERING set on. + * + * Notes: + * (1) the CTE (color table entry) index is sequentially + * assigned as the tree is pruned back + * (2) if 'bleaf' == 1, all pixels in that cube have been + * assigned to one or more CTEs. But note that if + * all 8 subcubes have 'bleaf' == 1, it will have no + * pixels left for assignment and will not be a CTE. + * (3) 'nleaves', the number of leaves contained at the next + * lower level is some number between 0 and 8, inclusive. + * If it is zero, it means that all colors within this cube + * are part of a single growing cluster that has not yet + * been set aside as a leaf. If 'nleaves' > 0, 'bleaf' + * will be set to 1 and all pixels not assigned to leaves + * at lower levels will be assigned to a CTE here. + * (However, as described above, if all pixels are already + * assigned, we set 'bleaf' = 1 but do not create a CTE + * at this level.) + * (4) To keep the maximum color error to a minimum, we + * prune the tree back to level 2, and require that + * all 64 level 2 cells are CTEs. + * (5) We reserve an extra set of colors to prevent running out + * of colors during the assignment of the final 64 level 2 cells. + * This is more likely to happen with small images. + * (6) When we run out of colors, the dithered image can be very + * poor, so we additionally prevent dithering if the image + * is small. + * (7) The color content of the image is measured, and if there + * is very little color, it is quantized in grayscale. + **/ struct ColorQuantCell { @@ -170,15 +174,19 @@ static const l_int32 TREE_GEN_WIDTH = 350; /* big enough for good stats */ static const l_int32 MIN_DITHER_SIZE = 250; /* don't dither if smaller */ -/* This data structure is used for pixOctreeQuantNumColors(), - * a color octree that adjusts in a simple way to the to the color - * distribution in the image that is being quantized. It outputs - * colormapped images, either 4 bpp or 8 bpp, depending on the - * max number of colors and the compression desired. +/* + *
+ * This data structure is used for pixOctreeQuantNumColors(), + * a color octree that adjusts in a simple way to the to the color + * distribution in the image that is being quantized. It outputs + * colormapped images, either 4 bpp or 8 bpp, depending on the + * max number of colors and the compression desired. * - * The number of samples is saved as a float in the first location, - * because this is required to use it as the key that orders the - * cells in the priority queue. */ + * The number of samples is saved as a float in the first location, + * because this is required to use it as the key that orders the + * cells in the priority queue. + *+ * */ struct OctcubeQuantCell { l_float32 n; /* number of samples in this cell */ @@ -189,8 +197,12 @@ struct OctcubeQuantCell typedef struct OctcubeQuantCell OQCELL; - /* This data structure is using for heap sorting octcubes - * by population. Sort order is decreasing. */ +/* + *
+ * This data structure is using for heap sorting octcubes + * by population. Sort order is decreasing. + *+ */ struct L_OctcubePop { l_float32 npix; /* parameter on which to sort */ @@ -201,12 +213,17 @@ struct L_OctcubePop }; typedef struct L_OctcubePop L_OCTCUBE_POP; - /* In pixDitherOctindexWithCmap(), we use these default values. - * To get the max value of 'dif' in the dithering color transfer, - * divide these "DIF_CAP" values by 8. However, a value of - * 0 means that there is no cap (infinite cap). A very small - * value is used for POP_DIF_CAP because dithering on the population - * generated colormap can be unstable without a tight cap. */ +/* + *
+ * In pixDitherOctindexWithCmap(), we use these default values. + To get the max value of 'dif' in the dithering color transfer, + divide these "DIF_CAP" values by 8. However, a value of + 0 means that there is no cap (infinite cap). A very small + value is used for POP_DIF_CAP because dithering on the population + generated colormap can be unstable without a tight cap. + *+ */ + static const l_int32 FIXED_DIF_CAP = 0; static const l_int32 POP_DIF_CAP = 40; @@ -265,6 +282,7 @@ static PIX *pixOctcubeQuantFromCmapLUT(PIX *pixs, PIXCMAP *cmap, * \param[in] ditherflag 1 to dither, 0 otherwise * \return pixd 8 bpp with colormap, or NULL on error * + *
* I found one description in the literature of octree color * quantization, using progressive truncation of the octree, * by M. Gervautz and W. Purgathofer in Graphics Gems, pp. @@ -511,6 +529,7 @@ static PIX *pixOctcubeQuantFromCmapLUT(PIX *pixs, PIXCMAP *cmap, * image can be very poor. As this would only happen with very * small images, and dithering is not particularly noticeable with * such images, turn it off. + **/ PIX * pixOctreeColorQuant(PIX *pixs, @@ -1304,6 +1323,7 @@ CQCELL **cqca; * \param[in] cqlevels can be 1, 2, 3, 4, 5 or 6 * \return 0 if OK; 1 on error * + *
* Set up tables. e.g., for cqlevels = 5, we need an integer 0 < i < 2^15: * rtab = 0 i7 0 0 i6 0 0 i5 0 0 i4 0 0 i3 0 0 * gtab = 0 0 i7 0 0 i6 0 0 i5 0 0 i4 0 0 i3 0 @@ -1323,6 +1343,7 @@ CQCELL **cqca; * 8 cubes. At level 2, each of these 8 octcubes is further divided into * 8 cubes, each labeled by the second most significant bits r6 g6 b6 * of the rgb color. + **/ l_int32 makeRGBToIndexTables(l_uint32 **prtab, @@ -1586,8 +1607,10 @@ getOctcubeIndices(l_int32 rgbindex, * \param[out] psize 2^(3 * level) cubes in the entire rgb cube * \return 0 if OK, 1 on error. Caller must check! * - * level: 1 2 3 4 5 6 - * size: 8 64 512 4098 32784 262272 + *
+ * level: 1 2 3 4 5 6 + * size: 8 64 512 4098 32784 262272 + **/ static l_int32 octcubeGetCount(l_int32 level, @@ -2143,6 +2166,7 @@ PIXCMAP *cmap; * use 0 for default * \return pixd 4 or 8 bpp, colormapped, or NULL on error * + *
* pixOctreeColorQuant is very flexible in terms of the relative * depth of different cubes of the octree. By contrast, this function, * pixOctreeQuantNumColors is also adaptive, but it supports octcube @@ -2219,6 +2243,7 @@ PIXCMAP *cmap; * example, in use one often finds that the pixels in an image * occupy less than 192 octcubes at level 3, so they can be represented * by a colormap for octcubes at level 3 only. + **/ PIX * pixOctreeQuantNumColors(PIX *pixs, @@ -2699,6 +2724,8 @@ PIXCMAP *cmap; * \param[in] ditherflag 1 for dithering; 0 for no dithering * \return pixd 8 bit with colormap, or NULL on error * + *
+ * Notes: * This simple 1-pass color quantization works by breaking the * color space into 256 pieces, with 3 bits quantized for each of * red and green, and 2 bits quantized for blue. We shortchange @@ -2751,6 +2778,7 @@ PIXCMAP *cmap; * However, without dithering, the loss of color accuracy is * evident in regions that are very light or that have subtle * blending of colors. + **/ PIX * pixFixedOctcubeQuant256(PIX *pixs, diff --git a/src/colorseg.c b/src/colorseg.c index 942061f6f..09bd143c9 100644 --- a/src/colorseg.c +++ b/src/colorseg.c @@ -75,9 +75,10 @@ static l_int32 pixColorSegmentTryCluster(PIX *pixd, PIX *pixs, * \param[in] finalcolors max number of final colors allowed after 4th pass * \return pixd 8 bit with colormap, or NULL on error * + *
* Color segmentation proceeds in four phases: * - * Phase 1: pixColorSegmentCluster + * Phase 1: pixColorSegmentCluster() * The image is traversed in raster order. Each pixel either * becomes the representative for a new cluster or is assigned to an * existing cluster. Assignment is greedy. The data is stored in @@ -85,21 +86,20 @@ static l_int32 pixColorSegmentTryCluster(PIX *pixd, PIX *pixs, * the colors of the representative pixels, for fast lookup. * The average color in each cluster is computed. * - * Phase 2. pixAssignToNearestColor + * Phase 2. pixAssignToNearestColor() * A second non-greedy clustering pass is performed, where each pixel * is assigned to the nearest cluster average. We also keep track * of how many pixels are assigned to each cluster. * - * Phase 3. pixColorSegmentClean + * Phase 3. pixColorSegmentClean() * For each cluster, starting with the largest, do a morphological * closing to eliminate small components within larger ones. * - * Phase 4. pixColorSegmentRemoveColors + * Phase 4. pixColorSegmentRemoveColors() * Eliminate all colors except the most populated 'finalcolors'. * Then remove unused colors from the colormap, and reassign those * pixels to the nearest remaining cluster, using the original pixel values. * - ** Notes: * (1) The goal is to generate a small number of colors. * Typically this would be specified by 'finalcolors', diff --git a/src/compare.c b/src/compare.c index 23a254bac..a2461d664 100644 --- a/src/compare.c +++ b/src/compare.c @@ -3280,8 +3280,8 @@ PIXA *pixa1, *pixa2, *pixadb; * alignment location, relative to pix1 * \param[in] tab8 [optional] sum tab for ON pixels in byte; can be NULL * \param[out] pdelx [optional] best x shift of pix2 relative to pix1 - * [out] pdely ([optional] best y shift of pix2 relative to pix1 - * [out] pscore ([optional] maximum score found; can be NULL + * \param[out] pdely ([optional] best y shift of pix2 relative to pix1 + * \param[out] pscore ([optional] maximum score found; can be NULL * \param[in] debugflag <= 0 to skip; positive to generate output. * The integer is used to label the debug image. * \return 0 if OK, 1 on error diff --git a/src/pix.h b/src/pix.h index 98265dcd0..d4d737b86 100644 --- a/src/pix.h +++ b/src/pix.h @@ -316,7 +316,8 @@ enum { #define PIX_PAINT (PIX_SRC | PIX_DST) /*!< paint = src | dst */ #define PIX_MASK (PIX_SRC & PIX_DST) /*!< mask = src & dst */ -#define PIX_SUBTRACT (PIX_DST & PIX_NOT(PIX_SRC)) /*!< subtract = src & !dst */ +#define PIX_SUBTRACT (PIX_DST & PIX_NOT(PIX_SRC)) /*!< subtract = */ + /*!< src & !dst */ #define PIX_XOR (PIX_SRC ^ PIX_DST) /*!< xor = src ^ dst */