From f99b05bfb9a2e883a53c6e8502fb1ac8289220f5 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 21 Oct 2006 03:12:42 +0000 Subject: fix pamperspective: read all of input git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@91 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- editor/pamperspective.c | 158 +++++++++++++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 63 deletions(-) (limited to 'editor/pamperspective.c') diff --git a/editor/pamperspective.c b/editor/pamperspective.c index 55ecd0f6..8ce746db 100644 --- a/editor/pamperspective.c +++ b/editor/pamperspective.c @@ -190,9 +190,15 @@ typedef struct { typedef struct { - int num_rows, last_physical, last_logical; - tuple** rows; - const struct pam* inpam; + unsigned int num_rows; + unsigned int last_physical; + unsigned int last_logical; + /* Row number of the input row most recently read from input + file into buffer (i.e. one less than the number of rows we + have read from the input) + */ + tuple ** rows; + const struct pam * inpamP; } buffer; @@ -1083,72 +1089,98 @@ static int clean_y (int const y, const struct pam *const outpam) return MIN(MAX(0, y), outpam->height-1); } -static void init_buffer (buffer *const b, const world_data *const world, - const option *const options, - const struct pam *const inpam, - const struct pam *const outpam) -{ - int yul, yur, yll, ylr, y_min; - int i, num_rows; - - yul = outpixel_to_iny (0,0,world); - yur = outpixel_to_iny (outpam->width-1,0,world); - yll = outpixel_to_iny (0,outpam->height-1,world); - ylr = outpixel_to_iny (outpam->width-1,outpam->height-1,world); - - y_min = MIN (MIN (yul,yur), MIN (yll,ylr)); - num_rows = MAX (MAX (diff (yul, yur), - diff (yll, ylr)), - MAX (diff (clean_y(yul,outpam), clean_y(y_min,outpam)), - diff (clean_y(yur,outpam), clean_y(y_min,outpam)))) - + 2; - switch (options->enums[3]) { /* --interpolation */ - case nearest: - break; - case linear: - num_rows += 1; - break; - }; - if (num_rows > inpam->height) - num_rows = inpam->height; - - b->num_rows = num_rows; - MALLOCARRAY_SAFE (b->rows, num_rows); - for (i=0; irows[i] = pnm_allocpamrow (inpam); - pnm_readpamrow (inpam, b->rows[i]); - }; - b->last_physical = num_rows-1; - b->last_logical = num_rows-1; - b->inpam = inpam; +static void +init_buffer(buffer * const bufferP, + const world_data * const worldP, + const option * const optionsP, + const struct pam * const inpamP, + const struct pam * const outpamP) { + + unsigned int yul, yur, yll, ylr, y_min; + unsigned int num_rows; + + yul = outpixel_to_iny(0, 0, worldP); + yur = outpixel_to_iny(outpamP->width-1, 0, worldP); + yll = outpixel_to_iny(0, outpamP->height-1, worldP); + ylr = outpixel_to_iny(outpamP->width-1, outpamP->height-1, worldP); + + y_min = MIN(MIN(yul, yur), MIN(yll, ylr)); + num_rows = MAX(MAX(diff(yul, yur), + diff(yll, ylr)), + MAX(diff(clean_y(yul, outpamP), clean_y(y_min, outpamP)), + diff(clean_y(yur, outpamP), clean_y(y_min, outpamP)))) + + 2; + switch (optionsP->enums[3]) { /* --interpolation */ + case nearest: + break; + case linear: + num_rows += 1; + break; + } + if (num_rows > inpamP->height) + num_rows = inpamP->height; + + MALLOCARRAY_SAFE(bufferP->rows, num_rows); + bufferP->num_rows = num_rows; + bufferP->last_logical = 0; + bufferP->last_physical = 0; + { + unsigned int row; + for (row = 0; row < num_rows; ++row) { + bufferP->rows[row] = pnm_allocpamrow(inpamP); + pnm_readpamrow(inpamP, bufferP->rows[row]); + ++bufferP->last_logical; + ++bufferP->last_physical; + } + } + bufferP->inpamP = inpamP; } -static tuple* read_buffer (buffer *const b, int const logical_y) -{ - int y; - - while (logical_y > b->last_logical) { - b->last_physical++; - if (b->last_physical == b->num_rows) - b->last_physical = 0; - pnm_readpamrow (b->inpam, b->rows[b->last_physical]); - b->last_logical++; - } - y = logical_y - b->last_logical + b->last_physical; - if (y<0) - y += b->num_rows; - return b->rows[y]; +static tuple * +read_buffer(buffer * const bufferP, + unsigned int const logical_y) { + + unsigned int y; + + while (logical_y > bufferP->last_logical) { + ++bufferP->last_physical; + if (bufferP->last_physical == bufferP->num_rows) + bufferP->last_physical = 0; + pnm_readpamrow(bufferP->inpamP, bufferP->rows[bufferP->last_physical]); + ++bufferP->last_logical; + } + + y = logical_y - bufferP->last_logical + bufferP->last_physical; + if (y < 0) + y += bufferP->num_rows; + + return bufferP->rows[y]; } -static void free_buffer (buffer *const b) -{ - int i; - for (i=0; inum_rows; i++) - pnm_freepamrow (b->rows[i]); - free (b->rows); + +static void +term_buffer(buffer * const bufferP) { + + unsigned int i; + + /* We have to read through the end of the input image even if we + didn't use all the rows, because if the input is a pipe, the + guy writing into the pipe may require all the data to go + through. + */ + + while (bufferP->last_logical < bufferP->inpamP->height-1) { + pnm_readpamrow(bufferP->inpamP, bufferP->rows[0]); + ++bufferP->last_logical; + } + + for (i = 0; i < bufferP->num_rows; ++i) + pnm_freepamrow(bufferP->rows[i]); + + free(bufferP->rows); } @@ -1331,7 +1363,7 @@ main(int argc, char* argv[]) { perspective(&outpam, &world, interpolater); clean_interpolation_global_vars(); - free_buffer(&inbuffer); + term_buffer(&inbuffer); free_option(&options); pm_close(ifP); pm_close(stdout); -- cgit 1.4.1