From 67e41068ab7531b3bd5bf40036d0d9a36071d036 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 24 May 2008 20:36:09 +0000 Subject: Release 10.35.44 git-svn-id: http://svn.code.sf.net/p/netpbm/code/stable@633 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- Makefile.version | 2 +- analyzer/pamtilt.c | 134 ++++++++++++++++++++++++++++++++++++++++------------- doc/HISTORY | 12 +++++ editor/pamscale.c | 2 +- lib/libppmd.c | 18 ++++++- lib/ppmdraw.h | 4 ++ 6 files changed, 137 insertions(+), 35 deletions(-) diff --git a/Makefile.version b/Makefile.version index ec978db6..37bb786c 100644 --- a/Makefile.version +++ b/Makefile.version @@ -1,3 +1,3 @@ NETPBM_MAJOR_RELEASE = 10 NETPBM_MINOR_RELEASE = 35 -NETPBM_POINT_RELEASE = 43 +NETPBM_POINT_RELEASE = 44 diff --git a/analyzer/pamtilt.c b/analyzer/pamtilt.c index 3753955b..37b6c394 100644 --- a/analyzer/pamtilt.c +++ b/analyzer/pamtilt.c @@ -1,7 +1,7 @@ /*============================================================================= - pgmtilt + pamtilt =============================================================================== - Print the tilt angle of a PGM file + Print the tilt angle of an image (typically black and white text). Based on pgmskew by Gregg Townsend, August 2005. @@ -10,6 +10,7 @@ All work has been contributed to the public domain by its authors. =============================================================================*/ +#include #include #include "pam.h" @@ -211,40 +212,39 @@ replacePixelValuesWithScaledDiffs( static void -scoreAngle(const struct pam * const pamP, - sample ** const pixels, - unsigned int const hstep, - unsigned int const vstep, - unsigned int const hsamples, - float const deg, - float * const scoreP) { +scoreAngleRegion(sample ** const pixels, + unsigned int const hsamples, + unsigned int const startRow, + unsigned int const endRow, + unsigned int const vstep, + float const dy, + float * const scoreP) { /*---------------------------------------------------------------------------- - calculate score for a given angle + Same as scoreAngle(), but we look only at the region from 'startRow' + to 'endRow', which we assume is enough inside the image that tilted + lines starting at the left within that region don't run off the top + or bottom of the image. + + We assume 'startRow' and 'endRow' are within the image and denote at + least one row. + + Instead of a tilt angle, we have 'dy', the slope (downward) of the lines + in our assumed tilt. -----------------------------------------------------------------------------*/ - float const radians = (float)deg/360 * 2 * M_PI; - float const dy = hstep * tan(radians); - int const dtotal = pamP->width * tan(radians); double const tscale = 1.0 / hsamples; - double total; - int first; - int last; - unsigned int row; - - total = 0.0; /* initial value */ - - if (dtotal > 0) { - first = 0; - last = pamP->height - 1 - (dtotal + 1); - } else { - first = -(dtotal - 1); - last = pamP->height - 1; - } - for (row = first; row < last; row += vstep) { + double sum; + /* Sum of brightness measure of all sampled lines which are + (assuming tilt) contained within image. + */ + unsigned int n; + /* Number of lines that went into 'total' */ + + for (row = startRow, sum = 0.0, n = 0; row < endRow; row += vstep) { float o; - long t; - double dt; + long t; /* total brightness of the samples in the line */ + double dt; /* mean brightness of the samples in the line */ unsigned int i; @@ -253,9 +253,79 @@ scoreAngle(const struct pam * const pamP, ++i, t += pixels[(int)(row + o)][i], o += dy) { } dt = tscale * t; - total += dt * dt; + sum += dt * dt; + n += 1; + } + assert(n > 0); /* Because we assume there's at least one row */ + *scoreP = sum / n; +} + + + +static void +scoreAngle(const struct pam * const pamP, + sample ** const pixels, + unsigned int const hstep, + unsigned int const vstep, + unsigned int const hsamples, + float const angle, + float * const scoreP) { +/*---------------------------------------------------------------------------- + Calculate the score for assuming the image described by *pamP and + 'pixels' is tilted down by angle 'angle' (in degrees) from what it + should be. I.e. the angle from the top edge of the paper to the + lines of text in the image is 'angle'. + + The score is a measure of how bright the lines of the image are if + we assume this angle. If the angle is right, there should be lots + of lines that are all white, because they are between lines of text. + If the angle is wrong, many lines will cross over lines of text and + thus be less that all white. A higher score indicates 'angle' is more + likely to be the angle at which the image is tilted. + + If 'angle' is so great that not a single line goes all the way across the + page without running off the top or bottom, we call the score -1. In + every other case, it is nonnegative. + + 'pixels' is NOT all the pixels in the image; it is just a sampling. + In each row, it contains only 'hsamples' pixels, sampled from the + image at intervals of 'hstep' pixels. E.g if the image is 1000 + pixels wide, pixels might be only 10 pixels wide, containing columns + 0, 100, 200, etc. of the image. + + Return the score as *scoreP. +-----------------------------------------------------------------------------*/ + float const radians = (float)angle/360 * 2 * M_PI; + float const dy = hstep * tan(radians); + /* How much a line sinks due to the tilt when we move one sample + ('hstep' columns of the image) to the right. + */ + if (fabs(dy * hsamples) > pamP->height) { + /* This is so tilted that not a single line of the image fits + entirely on the page, so we can't do the measurement. + */ + *scoreP = -1.0; + } else { + unsigned int startRow, endRow; + + if (dy > 0) { + /* Lines of image drop as you go right, so the bottommost lines go + off the page and we can't follow them. + */ + startRow = 0; + endRow = pamP->height - dy * hsamples; + } else { + /* Lines of image rise as you go right, so the topmost lines go + off the page and we can't follow them. + */ + startRow = 0 - dy * hsamples; + endRow = pamP->height; + } + assert(endRow > startRow); /* because of 'if (fabs(dy ...' */ + + scoreAngleRegion(pixels, hsamples, startRow, endRow, vstep, dy, + scoreP); } - *scoreP = total / (last - first); } diff --git a/doc/HISTORY b/doc/HISTORY index 6c3543e5..080082e9 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -4,6 +4,18 @@ Netpbm. CHANGE HISTORY -------------- +08.05.24 BJH Release 10.35.44 + + pamscale: fix PBM input + -nomix. + + pamtilt: fix crash with excessive angle. + + ppmd_filledrectangle(): fix crash with rectangle that is + entirely left or right of the image. + + Add back ppmd_fill_init() for backward compatibility; + removed in 10.29. + 08.05.10 BJH Release 10.35.43 pbmtext: fail properly if input contains no text. diff --git a/editor/pamscale.c b/editor/pamscale.c index 229fce42..94f67414 100644 --- a/editor/pamscale.c +++ b/editor/pamscale.c @@ -2095,7 +2095,7 @@ main(int argc, char **argv ) { outpam = inpam; /* initial value */ outpam.file = stdout; - if (PNM_FORMAT_TYPE(inpam.format) == PBM_TYPE) { + if (PNM_FORMAT_TYPE(inpam.format) == PBM_TYPE && !cmdline.nomix) { outpam.format = PGM_TYPE; outpam.maxval = PGM_MAXMAXVAL; pm_message("promoting from PBM to PGM"); diff --git a/lib/libppmd.c b/lib/libppmd.c index ac8b6dee..f2852338 100644 --- a/lib/libppmd.c +++ b/lib/libppmd.c @@ -114,7 +114,7 @@ ppmd_filledrectangle(pixel ** const pixels, /* Draw. */ for (row = cy; row < cy + cheight; ++row) { - unsigned int col; + int col; for (col = cx; col < cx + cwidth; ++col) drawPoint(drawProc, clientdata, pixels, cols, rows, maxval, col, row); @@ -676,6 +676,22 @@ ppmd_fill_create(void) { +char * +ppmd_fill_init(void) { +/*---------------------------------------------------------------------------- + Backward compatibility interface. This is what was used before + ppmd_fill_create() existed. + + Note that old programs treat a fill handle as a pointer to char + rather than a pointer to fillObj, and backward compatibility + depends upon the fact that these are implemented as identical types + (an address). +-----------------------------------------------------------------------------*/ + return (char *)ppmd_fill_create(); +} + + + void ppmd_fill_destroy(struct fillobj * fillObjP) { diff --git a/lib/ppmdraw.h b/lib/ppmdraw.h index 6a379573..7441cc43 100644 --- a/lib/ppmdraw.h +++ b/lib/ppmdraw.h @@ -237,6 +237,10 @@ ppmd_fill_create(void); void ppmd_fill_destroy(struct fillobj * fillObjP); +/* For backward compatibility only: */ +char * +ppmd_fill_init(void); + void ppmd_fill_drawproc(pixel ** const pixels, int const cols, -- cgit 1.4.1