1*4882a593SmuzhiyunFrom 0ab805f46f68500da3b49d6f89380bab169bf6bb Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Su Laus <sulau@freenet.de> 3*4882a593SmuzhiyunDate: Tue, 10 May 2022 20:03:17 +0000 4*4882a593SmuzhiyunSubject: [PATCH] tiffcrop: Fix issue #330 and some more from 320 to 349 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunUpstream-Status: Backport 7*4882a593SmuzhiyunSigned-off-by: Zheng Qiu <zheng.qiu@windriver.com> 8*4882a593Smuzhiyun--- 9*4882a593Smuzhiyun tools/tiffcrop.c | 282 +++++++++++++++++++++++++++++++++++------------ 10*4882a593Smuzhiyun 1 file changed, 210 insertions(+), 72 deletions(-) 11*4882a593Smuzhiyun 12*4882a593Smuzhiyundiff --git a/tools/tiffcrop.c b/tools/tiffcrop.c 13*4882a593Smuzhiyunindex 99e4208..b596f9e 100644 14*4882a593Smuzhiyun--- a/tools/tiffcrop.c 15*4882a593Smuzhiyun+++ b/tools/tiffcrop.c 16*4882a593Smuzhiyun@@ -63,20 +63,24 @@ 17*4882a593Smuzhiyun * units when sectioning image into columns x rows 18*4882a593Smuzhiyun * using the -S cols:rows option. 19*4882a593Smuzhiyun * -X # Horizontal dimension of region to extract expressed in current 20*4882a593Smuzhiyun- * units 21*4882a593Smuzhiyun+ * units, relative to the specified origin reference 'edge' left (default for X) or right. 22*4882a593Smuzhiyun * -Y # Vertical dimension of region to extract expressed in current 23*4882a593Smuzhiyun- * units 24*4882a593Smuzhiyun+ * units, relative to the specified origin reference 'edge' top (default for Y) or bottom. 25*4882a593Smuzhiyun * -O orient Orientation for output image, portrait, landscape, auto 26*4882a593Smuzhiyun * -P page Page size for output image segments, eg letter, legal, tabloid, 27*4882a593Smuzhiyun * etc. 28*4882a593Smuzhiyun * -S cols:rows Divide the image into equal sized segments using cols across 29*4882a593Smuzhiyun * and rows down 30*4882a593Smuzhiyun- * -E t|l|r|b Edge to use as origin 31*4882a593Smuzhiyun+ * -E t|l|r|b Edge to use as origin (i.e. 'side' of the image not 'corner') 32*4882a593Smuzhiyun+ * top = width from left, zones from top to bottom (default) 33*4882a593Smuzhiyun+ * bottom = width from left, zones from bottom to top 34*4882a593Smuzhiyun+ * left = zones from left to right, length from top 35*4882a593Smuzhiyun+ * right = zones from right to left, length from top 36*4882a593Smuzhiyun * -m #,#,#,# Margins from edges for selection: top, left, bottom, right 37*4882a593Smuzhiyun * (commas separated) 38*4882a593Smuzhiyun * -Z #:#,#:# Zones of the image designated as zone X of Y, 39*4882a593Smuzhiyun * eg 1:3 would be first of three equal portions measured 40*4882a593Smuzhiyun- * from reference edge 41*4882a593Smuzhiyun+ * from reference edge (i.e. 'side' not corner) 42*4882a593Smuzhiyun * -N odd|even|#,#-#,#|last 43*4882a593Smuzhiyun * Select sequences and/or ranges of images within file 44*4882a593Smuzhiyun * to process. The words odd or even may be used to specify 45*4882a593Smuzhiyun@@ -103,10 +107,13 @@ 46*4882a593Smuzhiyun * selects which functions dump data, with higher numbers selecting 47*4882a593Smuzhiyun * lower level, scanline level routines. Debug reports a limited set 48*4882a593Smuzhiyun * of messages to monitor progress without enabling dump logs. 49*4882a593Smuzhiyun+ * 50*4882a593Smuzhiyun+ * Note: The (-X|-Y), -Z and -z options are mutually exclusive. 51*4882a593Smuzhiyun+ * In no case should the options be applied to a given selection successively. 52*4882a593Smuzhiyun */ 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun-static char tiffcrop_version_id[] = "2.4.1"; 55*4882a593Smuzhiyun-static char tiffcrop_rev_date[] = "03-03-2010"; 56*4882a593Smuzhiyun+static char tiffcrop_version_id[] = "2.5"; 57*4882a593Smuzhiyun+static char tiffcrop_rev_date[] = "02-09-2022"; 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun #include "tif_config.h" 60*4882a593Smuzhiyun #include "libport.h" 61*4882a593Smuzhiyun@@ -774,6 +781,9 @@ static const char usage_info[] = 62*4882a593Smuzhiyun " The four debug/dump options are independent, though it makes little sense to\n" 63*4882a593Smuzhiyun " specify a dump file without specifying a detail level.\n" 64*4882a593Smuzhiyun "\n" 65*4882a593Smuzhiyun+"Note: The (-X|-Y), -Z and -z options are mutually exclusive.\n" 66*4882a593Smuzhiyun+" In no case should the options be applied to a given selection successively.\n" 67*4882a593Smuzhiyun+"\n" 68*4882a593Smuzhiyun ; 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun /* This function could be modified to pass starting sample offset 71*4882a593Smuzhiyun@@ -2123,6 +2133,15 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 72*4882a593Smuzhiyun /*NOTREACHED*/ 73*4882a593Smuzhiyun } 74*4882a593Smuzhiyun } 75*4882a593Smuzhiyun+ /*-- Check for not allowed combinations (e.g. -X, -Y and -Z and -z are mutually exclusive) --*/ 76*4882a593Smuzhiyun+ char XY, Z, R; 77*4882a593Smuzhiyun+ XY = ((crop_data->crop_mode & CROP_WIDTH) || (crop_data->crop_mode & CROP_LENGTH)); 78*4882a593Smuzhiyun+ Z = (crop_data->crop_mode & CROP_ZONES); 79*4882a593Smuzhiyun+ R = (crop_data->crop_mode & CROP_REGIONS); 80*4882a593Smuzhiyun+ if ((XY && Z) || (XY && R) || (Z && R)) { 81*4882a593Smuzhiyun+ TIFFError("tiffcrop input error", "The crop options(-X|-Y), -Z and -z are mutually exclusive.->Exit"); 82*4882a593Smuzhiyun+ exit(EXIT_FAILURE); 83*4882a593Smuzhiyun+ } 84*4882a593Smuzhiyun } /* end process_command_opts */ 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun /* Start a new output file if one has not been previously opened or 87*4882a593Smuzhiyun@@ -2748,7 +2767,7 @@ extractContigSamplesBytes (uint8_t *in, uint8_t *out, uint32_t cols, 88*4882a593Smuzhiyun tsample_t count, uint32_t start, uint32_t end) 89*4882a593Smuzhiyun { 90*4882a593Smuzhiyun int i, bytes_per_sample, sindex; 91*4882a593Smuzhiyun- uint32_t col, dst_rowsize, bit_offset; 92*4882a593Smuzhiyun+ uint32_t col, dst_rowsize, bit_offset, numcols; 93*4882a593Smuzhiyun uint32_t src_byte /*, src_bit */; 94*4882a593Smuzhiyun uint8_t *src = in; 95*4882a593Smuzhiyun uint8_t *dst = out; 96*4882a593Smuzhiyun@@ -2759,6 +2778,10 @@ extractContigSamplesBytes (uint8_t *in, uint8_t *out, uint32_t cols, 97*4882a593Smuzhiyun return (1); 98*4882a593Smuzhiyun } 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun+ /* Number of extracted columns shall be kept as (end-start + 1). Otherwise buffer-overflow might occur. 101*4882a593Smuzhiyun+ * 'start' and 'col' count from 0 to (cols-1) but 'end' is to be set one after the index of the last column to be copied! 102*4882a593Smuzhiyun+ */ 103*4882a593Smuzhiyun+ numcols = abs(end - start); 104*4882a593Smuzhiyun if ((start > end) || (start > cols)) 105*4882a593Smuzhiyun { 106*4882a593Smuzhiyun TIFFError ("extractContigSamplesBytes", 107*4882a593Smuzhiyun@@ -2771,6 +2794,9 @@ extractContigSamplesBytes (uint8_t *in, uint8_t *out, uint32_t cols, 108*4882a593Smuzhiyun "Invalid end column value %"PRIu32" ignored", end); 109*4882a593Smuzhiyun end = cols; 110*4882a593Smuzhiyun } 111*4882a593Smuzhiyun+ if (abs(end - start) > numcols) { 112*4882a593Smuzhiyun+ end = start + numcols; 113*4882a593Smuzhiyun+ } 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun dst_rowsize = (bps * (end - start) * count) / 8; 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun@@ -2814,7 +2840,7 @@ extractContigSamples8bits (uint8_t *in, uint8_t *out, uint32_t cols, 118*4882a593Smuzhiyun tsample_t count, uint32_t start, uint32_t end) 119*4882a593Smuzhiyun { 120*4882a593Smuzhiyun int ready_bits = 0, sindex = 0; 121*4882a593Smuzhiyun- uint32_t col, src_byte, src_bit, bit_offset; 122*4882a593Smuzhiyun+ uint32_t col, src_byte, src_bit, bit_offset, numcols; 123*4882a593Smuzhiyun uint8_t maskbits = 0, matchbits = 0; 124*4882a593Smuzhiyun uint8_t buff1 = 0, buff2 = 0; 125*4882a593Smuzhiyun uint8_t *src = in; 126*4882a593Smuzhiyun@@ -2826,6 +2852,10 @@ extractContigSamples8bits (uint8_t *in, uint8_t *out, uint32_t cols, 127*4882a593Smuzhiyun return (1); 128*4882a593Smuzhiyun } 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun+ /* Number of extracted columns shall be kept as (end-start + 1). Otherwise buffer-overflow might occur. 131*4882a593Smuzhiyun+ * 'start' and 'col' count from 0 to (cols-1) but 'end' is to be set one after the index of the last column to be copied! 132*4882a593Smuzhiyun+ */ 133*4882a593Smuzhiyun+ numcols = abs(end - start); 134*4882a593Smuzhiyun if ((start > end) || (start > cols)) 135*4882a593Smuzhiyun { 136*4882a593Smuzhiyun TIFFError ("extractContigSamples8bits", 137*4882a593Smuzhiyun@@ -2838,7 +2868,10 @@ extractContigSamples8bits (uint8_t *in, uint8_t *out, uint32_t cols, 138*4882a593Smuzhiyun "Invalid end column value %"PRIu32" ignored", end); 139*4882a593Smuzhiyun end = cols; 140*4882a593Smuzhiyun } 141*4882a593Smuzhiyun- 142*4882a593Smuzhiyun+ if (abs(end - start) > numcols) { 143*4882a593Smuzhiyun+ end = start + numcols; 144*4882a593Smuzhiyun+ } 145*4882a593Smuzhiyun+ 146*4882a593Smuzhiyun ready_bits = 0; 147*4882a593Smuzhiyun maskbits = (uint8_t)-1 >> (8 - bps); 148*4882a593Smuzhiyun buff1 = buff2 = 0; 149*4882a593Smuzhiyun@@ -2891,7 +2924,7 @@ extractContigSamples16bits (uint8_t *in, uint8_t *out, uint32_t cols, 150*4882a593Smuzhiyun tsample_t count, uint32_t start, uint32_t end) 151*4882a593Smuzhiyun { 152*4882a593Smuzhiyun int ready_bits = 0, sindex = 0; 153*4882a593Smuzhiyun- uint32_t col, src_byte, src_bit, bit_offset; 154*4882a593Smuzhiyun+ uint32_t col, src_byte, src_bit, bit_offset, numcols; 155*4882a593Smuzhiyun uint16_t maskbits = 0, matchbits = 0; 156*4882a593Smuzhiyun uint16_t buff1 = 0, buff2 = 0; 157*4882a593Smuzhiyun uint8_t bytebuff = 0; 158*4882a593Smuzhiyun@@ -2904,6 +2937,10 @@ extractContigSamples16bits (uint8_t *in, uint8_t *out, uint32_t cols, 159*4882a593Smuzhiyun return (1); 160*4882a593Smuzhiyun } 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun+ /* Number of extracted columns shall be kept as (end-start + 1). Otherwise buffer-overflow might occur. 163*4882a593Smuzhiyun+ * 'start' and 'col' count from 0 to (cols-1) but 'end' is to be set one after the index of the last column to be copied! 164*4882a593Smuzhiyun+ */ 165*4882a593Smuzhiyun+ numcols = abs(end - start); 166*4882a593Smuzhiyun if ((start > end) || (start > cols)) 167*4882a593Smuzhiyun { 168*4882a593Smuzhiyun TIFFError ("extractContigSamples16bits", 169*4882a593Smuzhiyun@@ -2916,6 +2953,9 @@ extractContigSamples16bits (uint8_t *in, uint8_t *out, uint32_t cols, 170*4882a593Smuzhiyun "Invalid end column value %"PRIu32" ignored", end); 171*4882a593Smuzhiyun end = cols; 172*4882a593Smuzhiyun } 173*4882a593Smuzhiyun+ if (abs(end - start) > numcols) { 174*4882a593Smuzhiyun+ end = start + numcols; 175*4882a593Smuzhiyun+ } 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun ready_bits = 0; 178*4882a593Smuzhiyun maskbits = (uint16_t)-1 >> (16 - bps); 179*4882a593Smuzhiyun@@ -2980,7 +3020,7 @@ extractContigSamples24bits (uint8_t *in, uint8_t *out, uint32_t cols, 180*4882a593Smuzhiyun tsample_t count, uint32_t start, uint32_t end) 181*4882a593Smuzhiyun { 182*4882a593Smuzhiyun int ready_bits = 0, sindex = 0; 183*4882a593Smuzhiyun- uint32_t col, src_byte, src_bit, bit_offset; 184*4882a593Smuzhiyun+ uint32_t col, src_byte, src_bit, bit_offset, numcols; 185*4882a593Smuzhiyun uint32_t maskbits = 0, matchbits = 0; 186*4882a593Smuzhiyun uint32_t buff1 = 0, buff2 = 0; 187*4882a593Smuzhiyun uint8_t bytebuff1 = 0, bytebuff2 = 0; 188*4882a593Smuzhiyun@@ -2993,6 +3033,10 @@ extractContigSamples24bits (uint8_t *in, uint8_t *out, uint32_t cols, 189*4882a593Smuzhiyun return (1); 190*4882a593Smuzhiyun } 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun+ /* Number of extracted columns shall be kept as (end-start + 1). Otherwise buffer-overflow might occur. 193*4882a593Smuzhiyun+ * 'start' and 'col' count from 0 to (cols-1) but 'end' is to be set one after the index of the last column to be copied! 194*4882a593Smuzhiyun+ */ 195*4882a593Smuzhiyun+ numcols = abs(end - start); 196*4882a593Smuzhiyun if ((start > end) || (start > cols)) 197*4882a593Smuzhiyun { 198*4882a593Smuzhiyun TIFFError ("extractContigSamples24bits", 199*4882a593Smuzhiyun@@ -3005,6 +3049,9 @@ extractContigSamples24bits (uint8_t *in, uint8_t *out, uint32_t cols, 200*4882a593Smuzhiyun "Invalid end column value %"PRIu32" ignored", end); 201*4882a593Smuzhiyun end = cols; 202*4882a593Smuzhiyun } 203*4882a593Smuzhiyun+ if (abs(end - start) > numcols) { 204*4882a593Smuzhiyun+ end = start + numcols; 205*4882a593Smuzhiyun+ } 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun ready_bits = 0; 208*4882a593Smuzhiyun maskbits = (uint32_t)-1 >> (32 - bps); 209*4882a593Smuzhiyun@@ -3089,7 +3136,7 @@ extractContigSamples32bits (uint8_t *in, uint8_t *out, uint32_t cols, 210*4882a593Smuzhiyun tsample_t count, uint32_t start, uint32_t end) 211*4882a593Smuzhiyun { 212*4882a593Smuzhiyun int ready_bits = 0, sindex = 0 /*, shift_width = 0 */; 213*4882a593Smuzhiyun- uint32_t col, src_byte, src_bit, bit_offset; 214*4882a593Smuzhiyun+ uint32_t col, src_byte, src_bit, bit_offset, numcols; 215*4882a593Smuzhiyun uint32_t longbuff1 = 0, longbuff2 = 0; 216*4882a593Smuzhiyun uint64_t maskbits = 0, matchbits = 0; 217*4882a593Smuzhiyun uint64_t buff1 = 0, buff2 = 0, buff3 = 0; 218*4882a593Smuzhiyun@@ -3104,6 +3151,10 @@ extractContigSamples32bits (uint8_t *in, uint8_t *out, uint32_t cols, 219*4882a593Smuzhiyun } 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun+ /* Number of extracted columns shall be kept as (end-start + 1). Otherwise buffer-overflow might occur. 223*4882a593Smuzhiyun+ * 'start' and 'col' count from 0 to (cols-1) but 'end' is to be set one after the index of the last column to be copied! 224*4882a593Smuzhiyun+ */ 225*4882a593Smuzhiyun+ numcols = abs(end - start); 226*4882a593Smuzhiyun if ((start > end) || (start > cols)) 227*4882a593Smuzhiyun { 228*4882a593Smuzhiyun TIFFError ("extractContigSamples32bits", 229*4882a593Smuzhiyun@@ -3116,6 +3167,9 @@ extractContigSamples32bits (uint8_t *in, uint8_t *out, uint32_t cols, 230*4882a593Smuzhiyun "Invalid end column value %"PRIu32" ignored", end); 231*4882a593Smuzhiyun end = cols; 232*4882a593Smuzhiyun } 233*4882a593Smuzhiyun+ if (abs(end - start) > numcols) { 234*4882a593Smuzhiyun+ end = start + numcols; 235*4882a593Smuzhiyun+ } 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun /* shift_width = ((bps + 7) / 8) + 1; */ 238*4882a593Smuzhiyun ready_bits = 0; 239*4882a593Smuzhiyun@@ -3195,7 +3249,7 @@ extractContigSamplesShifted8bits (uint8_t *in, uint8_t *out, uint32_t cols, 240*4882a593Smuzhiyun int shift) 241*4882a593Smuzhiyun { 242*4882a593Smuzhiyun int ready_bits = 0, sindex = 0; 243*4882a593Smuzhiyun- uint32_t col, src_byte, src_bit, bit_offset; 244*4882a593Smuzhiyun+ uint32_t col, src_byte, src_bit, bit_offset, numcols; 245*4882a593Smuzhiyun uint8_t maskbits = 0, matchbits = 0; 246*4882a593Smuzhiyun uint8_t buff1 = 0, buff2 = 0; 247*4882a593Smuzhiyun uint8_t *src = in; 248*4882a593Smuzhiyun@@ -3207,6 +3261,10 @@ extractContigSamplesShifted8bits (uint8_t *in, uint8_t *out, uint32_t cols, 249*4882a593Smuzhiyun return (1); 250*4882a593Smuzhiyun } 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun+ /* Number of extracted columns shall be kept as (end-start + 1). Otherwise buffer-overflow might occur. 253*4882a593Smuzhiyun+ * 'start' and 'col' count from 0 to (cols-1) but 'end' is to be set one after the index of the last column to be copied! 254*4882a593Smuzhiyun+ */ 255*4882a593Smuzhiyun+ numcols = abs(end - start); 256*4882a593Smuzhiyun if ((start > end) || (start > cols)) 257*4882a593Smuzhiyun { 258*4882a593Smuzhiyun TIFFError ("extractContigSamplesShifted8bits", 259*4882a593Smuzhiyun@@ -3219,6 +3277,9 @@ extractContigSamplesShifted8bits (uint8_t *in, uint8_t *out, uint32_t cols, 260*4882a593Smuzhiyun "Invalid end column value %"PRIu32" ignored", end); 261*4882a593Smuzhiyun end = cols; 262*4882a593Smuzhiyun } 263*4882a593Smuzhiyun+ if (abs(end - start) > numcols) { 264*4882a593Smuzhiyun+ end = start + numcols; 265*4882a593Smuzhiyun+ } 266*4882a593Smuzhiyun 267*4882a593Smuzhiyun ready_bits = shift; 268*4882a593Smuzhiyun maskbits = (uint8_t)-1 >> (8 - bps); 269*4882a593Smuzhiyun@@ -3275,7 +3336,7 @@ extractContigSamplesShifted16bits (uint8_t *in, uint8_t *out, uint32_t cols, 270*4882a593Smuzhiyun int shift) 271*4882a593Smuzhiyun { 272*4882a593Smuzhiyun int ready_bits = 0, sindex = 0; 273*4882a593Smuzhiyun- uint32_t col, src_byte, src_bit, bit_offset; 274*4882a593Smuzhiyun+ uint32_t col, src_byte, src_bit, bit_offset, numcols; 275*4882a593Smuzhiyun uint16_t maskbits = 0, matchbits = 0; 276*4882a593Smuzhiyun uint16_t buff1 = 0, buff2 = 0; 277*4882a593Smuzhiyun uint8_t bytebuff = 0; 278*4882a593Smuzhiyun@@ -3288,6 +3349,10 @@ extractContigSamplesShifted16bits (uint8_t *in, uint8_t *out, uint32_t cols, 279*4882a593Smuzhiyun return (1); 280*4882a593Smuzhiyun } 281*4882a593Smuzhiyun 282*4882a593Smuzhiyun+ /* Number of extracted columns shall be kept as (end-start + 1). Otherwise buffer-overflow might occur. 283*4882a593Smuzhiyun+ * 'start' and 'col' count from 0 to (cols-1) but 'end' is to be set one after the index of the last column to be copied! 284*4882a593Smuzhiyun+ */ 285*4882a593Smuzhiyun+ numcols = abs(end - start); 286*4882a593Smuzhiyun if ((start > end) || (start > cols)) 287*4882a593Smuzhiyun { 288*4882a593Smuzhiyun TIFFError ("extractContigSamplesShifted16bits", 289*4882a593Smuzhiyun@@ -3300,6 +3365,9 @@ extractContigSamplesShifted16bits (uint8_t *in, uint8_t *out, uint32_t cols, 290*4882a593Smuzhiyun "Invalid end column value %"PRIu32" ignored", end); 291*4882a593Smuzhiyun end = cols; 292*4882a593Smuzhiyun } 293*4882a593Smuzhiyun+ if (abs(end - start) > numcols) { 294*4882a593Smuzhiyun+ end = start + numcols; 295*4882a593Smuzhiyun+ } 296*4882a593Smuzhiyun 297*4882a593Smuzhiyun ready_bits = shift; 298*4882a593Smuzhiyun maskbits = (uint16_t)-1 >> (16 - bps); 299*4882a593Smuzhiyun@@ -3365,7 +3433,7 @@ extractContigSamplesShifted24bits (uint8_t *in, uint8_t *out, uint32_t cols, 300*4882a593Smuzhiyun int shift) 301*4882a593Smuzhiyun { 302*4882a593Smuzhiyun int ready_bits = 0, sindex = 0; 303*4882a593Smuzhiyun- uint32_t col, src_byte, src_bit, bit_offset; 304*4882a593Smuzhiyun+ uint32_t col, src_byte, src_bit, bit_offset, numcols; 305*4882a593Smuzhiyun uint32_t maskbits = 0, matchbits = 0; 306*4882a593Smuzhiyun uint32_t buff1 = 0, buff2 = 0; 307*4882a593Smuzhiyun uint8_t bytebuff1 = 0, bytebuff2 = 0; 308*4882a593Smuzhiyun@@ -3378,6 +3446,16 @@ extractContigSamplesShifted24bits (uint8_t *in, uint8_t *out, uint32_t cols, 309*4882a593Smuzhiyun return (1); 310*4882a593Smuzhiyun } 311*4882a593Smuzhiyun 312*4882a593Smuzhiyun+ /* Number of extracted columns shall be kept as (end-start + 1). Otherwise buffer-overflow might occur. 313*4882a593Smuzhiyun+ * 'start' and 'col' count from 0 to (cols-1) but 'end' is to be set one after the index of the last column to be copied! 314*4882a593Smuzhiyun+ */ 315*4882a593Smuzhiyun+ /*--- Remark, which is true for all those functions extractCongigSamplesXXX() -- 316*4882a593Smuzhiyun+ * The mitigation of the start/end test does not allways make sense, because the function is often called with e.g.: 317*4882a593Smuzhiyun+ * start = 31; end = 32; cols = 32 to extract the last column in a 32x32 sample image. 318*4882a593Smuzhiyun+ * If then, a worng parameter (e.g. cols = 10) is provided, the mitigated settings would be start=0; end=1. 319*4882a593Smuzhiyun+ * Therefore, an error message and no copy action might be the better reaction to wrong parameter configurations. 320*4882a593Smuzhiyun+ */ 321*4882a593Smuzhiyun+ numcols = abs(end - start); 322*4882a593Smuzhiyun if ((start > end) || (start > cols)) 323*4882a593Smuzhiyun { 324*4882a593Smuzhiyun TIFFError ("extractContigSamplesShifted24bits", 325*4882a593Smuzhiyun@@ -3390,6 +3468,9 @@ extractContigSamplesShifted24bits (uint8_t *in, uint8_t *out, uint32_t cols, 326*4882a593Smuzhiyun "Invalid end column value %"PRIu32" ignored", end); 327*4882a593Smuzhiyun end = cols; 328*4882a593Smuzhiyun } 329*4882a593Smuzhiyun+ if (abs(end - start) > numcols) { 330*4882a593Smuzhiyun+ end = start + numcols; 331*4882a593Smuzhiyun+ } 332*4882a593Smuzhiyun 333*4882a593Smuzhiyun ready_bits = shift; 334*4882a593Smuzhiyun maskbits = (uint32_t)-1 >> (32 - bps); 335*4882a593Smuzhiyun@@ -3451,7 +3532,7 @@ extractContigSamplesShifted24bits (uint8_t *in, uint8_t *out, uint32_t cols, 336*4882a593Smuzhiyun buff2 = (buff2 << 8); 337*4882a593Smuzhiyun bytebuff2 = bytebuff1; 338*4882a593Smuzhiyun ready_bits -= 8; 339*4882a593Smuzhiyun- } 340*4882a593Smuzhiyun+ } 341*4882a593Smuzhiyun 342*4882a593Smuzhiyun return (0); 343*4882a593Smuzhiyun } /* end extractContigSamplesShifted24bits */ 344*4882a593Smuzhiyun@@ -3463,7 +3544,7 @@ extractContigSamplesShifted32bits (uint8_t *in, uint8_t *out, uint32_t cols, 345*4882a593Smuzhiyun int shift) 346*4882a593Smuzhiyun { 347*4882a593Smuzhiyun int ready_bits = 0, sindex = 0 /*, shift_width = 0 */; 348*4882a593Smuzhiyun- uint32_t col, src_byte, src_bit, bit_offset; 349*4882a593Smuzhiyun+ uint32_t col, src_byte, src_bit, bit_offset, numcols; 350*4882a593Smuzhiyun uint32_t longbuff1 = 0, longbuff2 = 0; 351*4882a593Smuzhiyun uint64_t maskbits = 0, matchbits = 0; 352*4882a593Smuzhiyun uint64_t buff1 = 0, buff2 = 0, buff3 = 0; 353*4882a593Smuzhiyun@@ -3478,6 +3559,10 @@ extractContigSamplesShifted32bits (uint8_t *in, uint8_t *out, uint32_t cols, 354*4882a593Smuzhiyun } 355*4882a593Smuzhiyun 356*4882a593Smuzhiyun 357*4882a593Smuzhiyun+ /* Number of extracted columns shall be kept as (end-start + 1). Otherwise buffer-overflow might occur. 358*4882a593Smuzhiyun+ * 'start' and 'col' count from 0 to (cols-1) but 'end' is to be set one after the index of the last column to be copied! 359*4882a593Smuzhiyun+ */ 360*4882a593Smuzhiyun+ numcols = abs(end - start); 361*4882a593Smuzhiyun if ((start > end) || (start > cols)) 362*4882a593Smuzhiyun { 363*4882a593Smuzhiyun TIFFError ("extractContigSamplesShifted32bits", 364*4882a593Smuzhiyun@@ -3490,6 +3575,9 @@ extractContigSamplesShifted32bits (uint8_t *in, uint8_t *out, uint32_t cols, 365*4882a593Smuzhiyun "Invalid end column value %"PRIu32" ignored", end); 366*4882a593Smuzhiyun end = cols; 367*4882a593Smuzhiyun } 368*4882a593Smuzhiyun+ if (abs(end - start) > numcols) { 369*4882a593Smuzhiyun+ end = start + numcols; 370*4882a593Smuzhiyun+ } 371*4882a593Smuzhiyun 372*4882a593Smuzhiyun /* shift_width = ((bps + 7) / 8) + 1; */ 373*4882a593Smuzhiyun ready_bits = shift; 374*4882a593Smuzhiyun@@ -5431,7 +5519,7 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt 375*4882a593Smuzhiyun { 376*4882a593Smuzhiyun struct offset offsets; 377*4882a593Smuzhiyun int i; 378*4882a593Smuzhiyun- int32_t test; 379*4882a593Smuzhiyun+ uint32_t uaux; 380*4882a593Smuzhiyun uint32_t seg, total, need_buff = 0; 381*4882a593Smuzhiyun uint32_t buffsize; 382*4882a593Smuzhiyun uint32_t zwidth, zlength; 383*4882a593Smuzhiyun@@ -5512,8 +5600,13 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt 384*4882a593Smuzhiyun seg = crop->zonelist[j].position; 385*4882a593Smuzhiyun total = crop->zonelist[j].total; 386*4882a593Smuzhiyun 387*4882a593Smuzhiyun- /* check for not allowed zone cases like 0:0; 4:3; etc. and skip that input */ 388*4882a593Smuzhiyun+ /* check for not allowed zone cases like 0:0; 4:3; or negative ones etc. and skip that input */ 389*4882a593Smuzhiyun+ if (crop->zonelist[j].position < 0 || crop->zonelist[j].total < 0) { 390*4882a593Smuzhiyun+ TIFFError("getCropOffsets", "Negative crop zone values %d:%d are not allowed, thus skipped.", crop->zonelist[j].position, crop->zonelist[j].total); 391*4882a593Smuzhiyun+ continue; 392*4882a593Smuzhiyun+ } 393*4882a593Smuzhiyun if (seg == 0 || total == 0 || seg > total) { 394*4882a593Smuzhiyun+ TIFFError("getCropOffsets", "Crop zone %d:%d is out of specification, thus skipped.", seg, total); 395*4882a593Smuzhiyun continue; 396*4882a593Smuzhiyun } 397*4882a593Smuzhiyun 398*4882a593Smuzhiyun@@ -5526,17 +5619,23 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt 399*4882a593Smuzhiyun 400*4882a593Smuzhiyun crop->regionlist[i].x1 = offsets.startx + 401*4882a593Smuzhiyun (uint32_t)(offsets.crop_width * 1.0 * (seg - 1) / total); 402*4882a593Smuzhiyun- test = (int32_t)offsets.startx + 403*4882a593Smuzhiyun- (int32_t)(offsets.crop_width * 1.0 * seg / total); 404*4882a593Smuzhiyun- if (test < 1 ) 405*4882a593Smuzhiyun- crop->regionlist[i].x2 = 0; 406*4882a593Smuzhiyun- else 407*4882a593Smuzhiyun- { 408*4882a593Smuzhiyun- if (test > (int32_t)(image->width - 1)) 409*4882a593Smuzhiyun+ /* FAULT: IMHO in the old code here, the calculation of x2 was based on wrong assumtions. The whole image was assumed and 'endy' and 'starty' are not respected anymore!*/ 410*4882a593Smuzhiyun+ /* NEW PROPOSED Code: Assumption: offsets are within image with top left corner as origin (0,0) and 'start' <= 'end'. */ 411*4882a593Smuzhiyun+ if (crop->regionlist[i].x1 > offsets.endx) { 412*4882a593Smuzhiyun+ crop->regionlist[i].x1 = offsets.endx; 413*4882a593Smuzhiyun+ } else if (crop->regionlist[i].x1 >= image->width) { 414*4882a593Smuzhiyun+ crop->regionlist[i].x1 = image->width - 1; 415*4882a593Smuzhiyun+ } 416*4882a593Smuzhiyun+ 417*4882a593Smuzhiyun+ crop->regionlist[i].x2 = offsets.startx + (uint32_t)(offsets.crop_width * 1.0 * seg / total); 418*4882a593Smuzhiyun+ if (crop->regionlist[i].x2 > 0) crop->regionlist[i].x2 = crop->regionlist[i].x2 - 1; 419*4882a593Smuzhiyun+ if (crop->regionlist[i].x2 < crop->regionlist[i].x1) { 420*4882a593Smuzhiyun+ crop->regionlist[i].x2 = crop->regionlist[i].x1; 421*4882a593Smuzhiyun+ } else if (crop->regionlist[i].x2 > offsets.endx) { 422*4882a593Smuzhiyun+ crop->regionlist[i].x2 = offsets.endx; 423*4882a593Smuzhiyun+ } else if (crop->regionlist[i].x2 >= image->width) { 424*4882a593Smuzhiyun crop->regionlist[i].x2 = image->width - 1; 425*4882a593Smuzhiyun- else 426*4882a593Smuzhiyun- crop->regionlist[i].x2 = test - 1; 427*4882a593Smuzhiyun- } 428*4882a593Smuzhiyun+ } 429*4882a593Smuzhiyun zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; 430*4882a593Smuzhiyun 431*4882a593Smuzhiyun /* This is passed to extractCropZone or extractCompositeZones */ 432*4882a593Smuzhiyun@@ -5551,22 +5650,27 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt 433*4882a593Smuzhiyun crop->regionlist[i].x1 = offsets.startx; 434*4882a593Smuzhiyun crop->regionlist[i].x2 = offsets.endx; 435*4882a593Smuzhiyun 436*4882a593Smuzhiyun- test = offsets.endy - (uint32_t)(offsets.crop_length * 1.0 * seg / total); 437*4882a593Smuzhiyun- if (test < 1 ) 438*4882a593Smuzhiyun- crop->regionlist[i].y1 = 0; 439*4882a593Smuzhiyun- else 440*4882a593Smuzhiyun- crop->regionlist[i].y1 = test + 1; 441*4882a593Smuzhiyun+ /* FAULT: IMHO in the old code here, the calculation of y1/y2 was based on wrong assumtions. The whole image was assumed and 'endy' and 'starty' are not respected anymore!*/ 442*4882a593Smuzhiyun+ /* NEW PROPOSED Code: Assumption: offsets are within image with top left corner as origin (0,0) and 'start' <= 'end'. */ 443*4882a593Smuzhiyun+ uaux = (uint32_t)(offsets.crop_length * 1.0 * seg / total); 444*4882a593Smuzhiyun+ if (uaux <= offsets.endy + 1) { 445*4882a593Smuzhiyun+ crop->regionlist[i].y1 = offsets.endy - uaux + 1; 446*4882a593Smuzhiyun+ } else { 447*4882a593Smuzhiyun+ crop->regionlist[i].y1 = 0; 448*4882a593Smuzhiyun+ } 449*4882a593Smuzhiyun+ if (crop->regionlist[i].y1 < offsets.starty) { 450*4882a593Smuzhiyun+ crop->regionlist[i].y1 = offsets.starty; 451*4882a593Smuzhiyun+ } 452*4882a593Smuzhiyun 453*4882a593Smuzhiyun- test = offsets.endy - (offsets.crop_length * 1.0 * (seg - 1) / total); 454*4882a593Smuzhiyun- if (test < 1 ) 455*4882a593Smuzhiyun- crop->regionlist[i].y2 = 0; 456*4882a593Smuzhiyun- else 457*4882a593Smuzhiyun- { 458*4882a593Smuzhiyun- if (test > (int32_t)(image->length - 1)) 459*4882a593Smuzhiyun- crop->regionlist[i].y2 = image->length - 1; 460*4882a593Smuzhiyun- else 461*4882a593Smuzhiyun- crop->regionlist[i].y2 = test; 462*4882a593Smuzhiyun- } 463*4882a593Smuzhiyun+ uaux = (uint32_t)(offsets.crop_length * 1.0 * (seg - 1) / total); 464*4882a593Smuzhiyun+ if (uaux <= offsets.endy) { 465*4882a593Smuzhiyun+ crop->regionlist[i].y2 = offsets.endy - uaux; 466*4882a593Smuzhiyun+ } else { 467*4882a593Smuzhiyun+ crop->regionlist[i].y2 = 0; 468*4882a593Smuzhiyun+ } 469*4882a593Smuzhiyun+ if (crop->regionlist[i].y2 < offsets.starty) { 470*4882a593Smuzhiyun+ crop->regionlist[i].y2 = offsets.starty; 471*4882a593Smuzhiyun+ } 472*4882a593Smuzhiyun zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1; 473*4882a593Smuzhiyun 474*4882a593Smuzhiyun /* This is passed to extractCropZone or extractCompositeZones */ 475*4882a593Smuzhiyun@@ -5577,32 +5681,42 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt 476*4882a593Smuzhiyun crop->combined_width = (uint32_t)zwidth; 477*4882a593Smuzhiyun break; 478*4882a593Smuzhiyun case EDGE_RIGHT: /* zones from right to left, length from top */ 479*4882a593Smuzhiyun- zlength = offsets.crop_length; 480*4882a593Smuzhiyun- crop->regionlist[i].y1 = offsets.starty; 481*4882a593Smuzhiyun- crop->regionlist[i].y2 = offsets.endy; 482*4882a593Smuzhiyun- 483*4882a593Smuzhiyun- crop->regionlist[i].x1 = offsets.startx + 484*4882a593Smuzhiyun- (uint32_t)(offsets.crop_width * (total - seg) * 1.0 / total); 485*4882a593Smuzhiyun- test = offsets.startx + 486*4882a593Smuzhiyun- (offsets.crop_width * (total - seg + 1) * 1.0 / total); 487*4882a593Smuzhiyun- if (test < 1 ) 488*4882a593Smuzhiyun- crop->regionlist[i].x2 = 0; 489*4882a593Smuzhiyun- else 490*4882a593Smuzhiyun- { 491*4882a593Smuzhiyun- if (test > (int32_t)(image->width - 1)) 492*4882a593Smuzhiyun- crop->regionlist[i].x2 = image->width - 1; 493*4882a593Smuzhiyun- else 494*4882a593Smuzhiyun- crop->regionlist[i].x2 = test - 1; 495*4882a593Smuzhiyun- } 496*4882a593Smuzhiyun- zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; 497*4882a593Smuzhiyun+ zlength = offsets.crop_length; 498*4882a593Smuzhiyun+ crop->regionlist[i].y1 = offsets.starty; 499*4882a593Smuzhiyun+ crop->regionlist[i].y2 = offsets.endy; 500*4882a593Smuzhiyun+ 501*4882a593Smuzhiyun+ crop->regionlist[i].x1 = offsets.startx + 502*4882a593Smuzhiyun+ (uint32_t)(offsets.crop_width * (total - seg) * 1.0 / total); 503*4882a593Smuzhiyun+ /* FAULT: IMHO from here on, the calculation of y2 are based on wrong assumtions. The whole image is assumed and 'endy' and 'starty' are not respected anymore!*/ 504*4882a593Smuzhiyun+ /* NEW PROPOSED Code: Assumption: offsets are within image with top left corner as origin (0,0) and 'start' <= 'end'. */ 505*4882a593Smuzhiyun+ uaux = (uint32_t)(offsets.crop_width * 1.0 * seg / total); 506*4882a593Smuzhiyun+ if (uaux <= offsets.endx + 1) { 507*4882a593Smuzhiyun+ crop->regionlist[i].x1 = offsets.endx - uaux + 1; 508*4882a593Smuzhiyun+ } else { 509*4882a593Smuzhiyun+ crop->regionlist[i].x1 = 0; 510*4882a593Smuzhiyun+ } 511*4882a593Smuzhiyun+ if (crop->regionlist[i].x1 < offsets.startx) { 512*4882a593Smuzhiyun+ crop->regionlist[i].x1 = offsets.startx; 513*4882a593Smuzhiyun+ } 514*4882a593Smuzhiyun 515*4882a593Smuzhiyun- /* This is passed to extractCropZone or extractCompositeZones */ 516*4882a593Smuzhiyun- crop->combined_length = (uint32_t)zlength; 517*4882a593Smuzhiyun- if (crop->exp_mode == COMPOSITE_IMAGES) 518*4882a593Smuzhiyun- crop->combined_width += (uint32_t)zwidth; 519*4882a593Smuzhiyun- else 520*4882a593Smuzhiyun- crop->combined_width = (uint32_t)zwidth; 521*4882a593Smuzhiyun- break; 522*4882a593Smuzhiyun+ uaux = (uint32_t)(offsets.crop_width * 1.0 * (seg - 1) / total); 523*4882a593Smuzhiyun+ if (uaux <= offsets.endx) { 524*4882a593Smuzhiyun+ crop->regionlist[i].x2 = offsets.endx - uaux; 525*4882a593Smuzhiyun+ } else { 526*4882a593Smuzhiyun+ crop->regionlist[i].x2 = 0; 527*4882a593Smuzhiyun+ } 528*4882a593Smuzhiyun+ if (crop->regionlist[i].x2 < offsets.startx) { 529*4882a593Smuzhiyun+ crop->regionlist[i].x2 = offsets.startx; 530*4882a593Smuzhiyun+ } 531*4882a593Smuzhiyun+ zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; 532*4882a593Smuzhiyun+ 533*4882a593Smuzhiyun+ /* This is passed to extractCropZone or extractCompositeZones */ 534*4882a593Smuzhiyun+ crop->combined_length = (uint32_t)zlength; 535*4882a593Smuzhiyun+ if (crop->exp_mode == COMPOSITE_IMAGES) 536*4882a593Smuzhiyun+ crop->combined_width += (uint32_t)zwidth; 537*4882a593Smuzhiyun+ else 538*4882a593Smuzhiyun+ crop->combined_width = (uint32_t)zwidth; 539*4882a593Smuzhiyun+ break; 540*4882a593Smuzhiyun case EDGE_TOP: /* width from left, zones from top to bottom */ 541*4882a593Smuzhiyun default: 542*4882a593Smuzhiyun zwidth = offsets.crop_width; 543*4882a593Smuzhiyun@@ -5610,6 +5724,14 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt 544*4882a593Smuzhiyun crop->regionlist[i].x2 = offsets.endx; 545*4882a593Smuzhiyun 546*4882a593Smuzhiyun crop->regionlist[i].y1 = offsets.starty + (uint32_t)(offsets.crop_length * 1.0 * (seg - 1) / total); 547*4882a593Smuzhiyun+ if (crop->regionlist[i].y1 > offsets.endy) { 548*4882a593Smuzhiyun+ crop->regionlist[i].y1 = offsets.endy; 549*4882a593Smuzhiyun+ } else if (crop->regionlist[i].y1 >= image->length) { 550*4882a593Smuzhiyun+ crop->regionlist[i].y1 = image->length - 1; 551*4882a593Smuzhiyun+ } 552*4882a593Smuzhiyun+ 553*4882a593Smuzhiyun+ /* FAULT: IMHO from here on, the calculation of y2 are based on wrong assumtions. The whole image is assumed and 'endy' and 'starty' are not respected anymore!*/ 554*4882a593Smuzhiyun+ /* OLD Code: 555*4882a593Smuzhiyun test = offsets.starty + (uint32_t)(offsets.crop_length * 1.0 * seg / total); 556*4882a593Smuzhiyun if (test < 1 ) 557*4882a593Smuzhiyun crop->regionlist[i].y2 = 0; 558*4882a593Smuzhiyun@@ -5620,6 +5742,18 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt 559*4882a593Smuzhiyun else 560*4882a593Smuzhiyun crop->regionlist[i].y2 = test - 1; 561*4882a593Smuzhiyun } 562*4882a593Smuzhiyun+ */ 563*4882a593Smuzhiyun+ /* NEW PROPOSED Code: Assumption: offsets are within image with top left corner as origin (0,0) and 'start' <= 'end'. */ 564*4882a593Smuzhiyun+ crop->regionlist[i].y2 = offsets.starty + (uint32_t)(offsets.crop_length * 1.0 * seg / total); 565*4882a593Smuzhiyun+ if (crop->regionlist[i].y2 > 0)crop->regionlist[i].y2 = crop->regionlist[i].y2 - 1; 566*4882a593Smuzhiyun+ if (crop->regionlist[i].y2 < crop->regionlist[i].y1) { 567*4882a593Smuzhiyun+ crop->regionlist[i].y2 = crop->regionlist[i].y1; 568*4882a593Smuzhiyun+ } else if (crop->regionlist[i].y2 > offsets.endy) { 569*4882a593Smuzhiyun+ crop->regionlist[i].y2 = offsets.endy; 570*4882a593Smuzhiyun+ } else if (crop->regionlist[i].y2 >= image->length) { 571*4882a593Smuzhiyun+ crop->regionlist[i].y2 = image->length - 1; 572*4882a593Smuzhiyun+ } 573*4882a593Smuzhiyun+ 574*4882a593Smuzhiyun zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1; 575*4882a593Smuzhiyun 576*4882a593Smuzhiyun /* This is passed to extractCropZone or extractCompositeZones */ 577*4882a593Smuzhiyun@@ -7543,7 +7677,8 @@ processCropSelections(struct image_data *image, struct crop_mask *crop, 578*4882a593Smuzhiyun total_width = total_length = 0; 579*4882a593Smuzhiyun for (i = 0; i < crop->selections; i++) 580*4882a593Smuzhiyun { 581*4882a593Smuzhiyun- cropsize = crop->bufftotal; 582*4882a593Smuzhiyun+ 583*4882a593Smuzhiyun+ cropsize = crop->bufftotal; 584*4882a593Smuzhiyun crop_buff = seg_buffs[i].buffer; 585*4882a593Smuzhiyun if (!crop_buff) 586*4882a593Smuzhiyun crop_buff = (unsigned char *)limitMalloc(cropsize); 587*4882a593Smuzhiyun@@ -7632,6 +7767,9 @@ processCropSelections(struct image_data *image, struct crop_mask *crop, 588*4882a593Smuzhiyun 589*4882a593Smuzhiyun if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */ 590*4882a593Smuzhiyun { 591*4882a593Smuzhiyun+ /* rotateImage() changes image->width, ->length, ->xres and ->yres, what it schouldn't do here, when more than one section is processed. 592*4882a593Smuzhiyun+ * ToDo: Therefore rotateImage() and its usage has to be reworked (e.g. like mirrorImage()) !! 593*4882a593Smuzhiyun+ */ 594*4882a593Smuzhiyun if (rotateImage(crop->rotation, image, &crop->regionlist[i].width, 595*4882a593Smuzhiyun &crop->regionlist[i].length, &crop_buff)) 596*4882a593Smuzhiyun { 597*4882a593Smuzhiyun@@ -7647,8 +7785,8 @@ processCropSelections(struct image_data *image, struct crop_mask *crop, 598*4882a593Smuzhiyun seg_buffs[i].size = (((crop->regionlist[i].width * image->bps + 7 ) / 8) 599*4882a593Smuzhiyun * image->spp) * crop->regionlist[i].length; 600*4882a593Smuzhiyun } 601*4882a593Smuzhiyun- } 602*4882a593Smuzhiyun- } 603*4882a593Smuzhiyun+ } /* for crop->selections loop */ 604*4882a593Smuzhiyun+ } /* Separated Images (else case) */ 605*4882a593Smuzhiyun return (0); 606*4882a593Smuzhiyun } /* end processCropSelections */ 607*4882a593Smuzhiyun 608