diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2020-08-22 23:04:22 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2020-08-22 23:04:22 +0000 |
commit | 7e040257350d11f891d2b7379e08adf94344480f (patch) | |
tree | d31e147e249038ee23e3f3ff3190ad67ea816fba /editor | |
parent | cef9e3fe7284012a932817a70c3b3639cff87932 (diff) | |
download | netpbm-mirror-7e040257350d11f891d2b7379e08adf94344480f.tar.gz netpbm-mirror-7e040257350d11f891d2b7379e08adf94344480f.tar.xz netpbm-mirror-7e040257350d11f891d2b7379e08adf94344480f.zip |
Make -margin effective with -blank=image=minimize
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3923 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'editor')
-rw-r--r-- | editor/pnmcrop.c | 162 |
1 files changed, 115 insertions, 47 deletions
diff --git a/editor/pnmcrop.c b/editor/pnmcrop.c index f41e67bd..43027da0 100644 --- a/editor/pnmcrop.c +++ b/editor/pnmcrop.c @@ -1123,64 +1123,135 @@ noCrops(struct CmdlineInfo const cmdline) { +static void +divideAllBackgroundIntoBorders(unsigned int const totalSz, + bool const wantCropSideA, + bool const wantCropSideB, + unsigned int const wantMargin, + unsigned int * const sideASzP, + unsigned int * const sideBSzP) { +/*---------------------------------------------------------------------------- + Divide up an all-background space into fictional borders (that can be + trimmed or padded). + + If there is to be a margin, those borders touch - the entire image is + borders. But if there is not to be a margin, there has to be one pixel, + row, or column between the borders so that there is something left after we + crop off those borders (because there's no such thing as a zero-pixel + image). + + This function does the borders in one direction - top and bottom or left + and right. Top or left is called "Side A"; bottom or right is called "Side + B". 'totalSz' is the width of the image in the top/bottom case and the + height of the image in the left/right case. +-----------------------------------------------------------------------------*/ + unsigned int sideASz, sideBSz; + + if (wantCropSideA && wantCropSideB) { + sideASz = totalSz/2; + if (wantMargin) + sideBSz = totalSz - sideASz; + else + sideBSz = totalSz - sideASz - 1; + } else if (wantCropSideA) { + if (wantMargin) + sideASz = totalSz; + else + sideASz = totalSz - 1; + sideBSz = 0; + } else if (wantCropSideB) { + sideASz = 0; + if (wantMargin) + sideBSz = totalSz; + else + sideBSz = totalSz - 1; + } else { + sideASz = 0; + sideBSz = 0; + } + *sideASzP = sideASz; + *sideBSzP = sideBSz; +} + + + +static CropOp +oneSideCrop(bool const wantCrop, + unsigned int const borderSz, + unsigned int const margin) { + + CropOp retval; + + if (wantCrop) { + if (borderSz >= margin) { + retval.removeSize = borderSz - margin; + retval.padSize = 0; + } else { + retval.removeSize = 0; + retval.padSize = margin - borderSz; + } + } else { + retval.removeSize = 0; + retval.padSize = 0; + } + + return retval; +} + + + static CropSet extremeCrops(struct CmdlineInfo const cmdline, unsigned int const cols, unsigned int const rows) { /*---------------------------------------------------------------------------- Crops that crop as much as possible, reducing output to a single - row, column, or pixel. + row, column, or pixel, plus margins. -----------------------------------------------------------------------------*/ CropSet retval; + unsigned int leftBorderSz, rghtBorderSz; + unsigned int topBorderSz, botBorderSz; + if (cmdline.verbose) pm_message("Input image has no distinction between " "border and content"); - /* We can't just pick a representative pixel, say top-left corner. - If -top and/or -bottom was specified but not -left and -right, - the output should be one row, not a single pixel. + /* Note that the "entirely background" image may have several colors: this + happens when -closeness was specified. That means we can't just build + up an image from background color - we actually have to preserve some + of the original image. - The "entirely background" image may have several colors: this - happens when -closeness was specified. + We divide the background into individual borders, with a foreground of + either nothing at all or a single row, column, or pixel, then crop + those fictional borders the same as if they were real. The "nothing + at all" case is feasible only when there is to be a margin, because + otherwise cropping the borders would leave nothing. */ - if (cmdline.wantCrop[LEFT] && cmdline.wantCrop[RIGHT]) { - retval.op[LEFT ].removeSize = cols / 2; - retval.op[RIGHT].removeSize = cols - retval.op[LEFT].removeSize -1; - } else if (cmdline.wantCrop[LEFT]) { - retval.op[LEFT ].removeSize = cols - 1; - retval.op[RIGHT].removeSize = 0; - } else if (cmdline.wantCrop[RIGHT]) { - retval.op[LEFT ].removeSize = 0; - retval.op[RIGHT].removeSize = cols - 1; - } else { - retval.op[LEFT ].removeSize = 0; - retval.op[RIGHT].removeSize = 0; - } - - if (cmdline.wantCrop[TOP] && cmdline.wantCrop[BOTTOM]) { - retval.op[ TOP ].removeSize = rows / 2; - retval.op[BOTTOM].removeSize = rows - retval.op[TOP].removeSize -1; - } else if (cmdline.wantCrop[TOP]) { - retval.op[ TOP ].removeSize = rows - 1; - retval.op[BOTTOM].removeSize = 0; - } else if (cmdline.wantCrop[BOTTOM]) { - retval.op[ TOP ].removeSize = 0; - retval.op[BOTTOM].removeSize = rows - 1; - } else { - retval.op[ TOP ].removeSize = 0; - retval.op[BOTTOM].removeSize = 0; - } + divideAllBackgroundIntoBorders(cols, + cmdline.wantCrop[LEFT], + cmdline.wantCrop[RIGHT], + cmdline.margin > 0, + &leftBorderSz, + &rghtBorderSz); + + divideAllBackgroundIntoBorders(rows, + cmdline.wantCrop[TOP], + cmdline.wantCrop[BOTTOM], + cmdline.margin > 0, + &topBorderSz, + &botBorderSz); + + retval.op[LEFT ] = + oneSideCrop(cmdline.wantCrop[LEFT ], leftBorderSz, cmdline.margin); + retval.op[RIGHT ] = + oneSideCrop(cmdline.wantCrop[RIGHT ], rghtBorderSz, cmdline.margin); + retval.op[TOP ] = + oneSideCrop(cmdline.wantCrop[TOP ], topBorderSz, cmdline.margin); + retval.op[BOTTOM] = + oneSideCrop(cmdline.wantCrop[BOTTOM], botBorderSz, cmdline.margin); - if (cmdline.margin > 0) - pm_message ("-margin value %u ignored", cmdline.margin); - - { - EdgeLocation i; - for (i = 0; i < ARRAY_SIZE(retval.op); ++i) - retval.op[i].padSize = 0; - } return retval; } @@ -1330,12 +1401,9 @@ cropOneImage(struct CmdlineInfo const cmdline, pm_error("The image is entirely background; " "there is nothing to crop."); break; - case BLANK_PASS: - crop = noCrops(cmdline); break; - case BLANK_MINIMIZE: - crop = extremeCrops(cmdline, cols, rows); break; - case BLANK_MAXCROP: - crop = maxcropReport(cmdline, cols, rows); break; + case BLANK_PASS: crop = noCrops(cmdline); break; + case BLANK_MINIMIZE: crop = extremeCrops(cmdline, cols, rows); break; + case BLANK_MAXCROP: crop = maxcropReport(cmdline, cols, rows); break; } } else { crop = crops(cmdline, oldBorder); |