--- OLD/pnm/pnmarith.c Thu Jan 1 00:00:00 1970 +++ NEW/pnm/pnmarith.c Thu Jan 1 00:00:00 1970 @@ -30,8 +30,13 @@ int argn, rows1, cols1, format1, rows2, cols2, format2, format3, row, col; char function; char* usage = -"-add|-subtract|-multiply|-difference|-minimum|-maximum pnmfile1 pnmfile2"; - +"-add|-subtract|-multiply|-difference|-minimum|-maximum|-average pnmfile1 pnmfile2"; + int orows; + int ocols; + int replicate1; + int replicate2; + xel *oxelrow; + xel *oxp; pnm_init( &argc, argv ); @@ -41,7 +46,7 @@ /* Check for flags. */ if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) { - if ( pm_keymatch( argv[argn], "-add", 2 ) ) + if ( pm_keymatch( argv[argn], "-add", 3 ) ) function = '+'; else if ( pm_keymatch( argv[argn], "-subtract", 2 ) ) function = '-'; @@ -49,10 +54,12 @@ function = '*'; else if ( pm_keymatch( argv[argn], "-difference", 2 ) ) function = 'D'; - else if ( pm_keymatch( argv[argn], "-minimum", 2 ) ) + else if ( pm_keymatch( argv[argn], "-minimum", 3 ) ) function = 'N'; - else if ( pm_keymatch( argv[argn], "-maximum", 2 ) ) + else if ( pm_keymatch( argv[argn], "-maximum", 3 ) ) function = 'X'; + else if ( pm_keymatch( argv[argn], "-average", 3 ) ) + function = 'V'; else pm_usage( usage ); ++argn; @@ -77,48 +84,62 @@ pnm_readpnminit( ifp1, &cols1, &rows1, &maxval1, &format1 ); xelrow1 = pnm_allocrow( cols1 ); pnm_readpnminit( ifp2, &cols2, &rows2, &maxval2, &format2 ); - if ( cols2 != cols1 || rows2 != rows1 ) - pm_error( - "the two anymaps must be the same width and height" ); - xelrow2 = pnm_allocrow( cols1 ); + xelrow2 = pnm_allocrow( cols2 ); + orows = rows1; + ocols = cols1; + if ((rows1 == 1) && (cols1 == 1)) + { replicate1 = 1; + replicate2 = 0; + orows = rows2; + ocols = cols2; + } + else if ((rows2 == 1) && (cols2 == 1)) + { replicate1 = 0; + replicate2 = 1; + } + else if ((rows2 != rows1) || (cols2 != cols1)) + { pm_error("the two anymaps must be the same width and height" ); + } + else + { replicate1 = 0; + replicate2 = 0; + } + oxelrow = pnm_allocrow(ocols); maxval3 = max( maxval1, maxval2 ); format3 = max( PNM_FORMAT_TYPE(format1), PNM_FORMAT_TYPE(format2) ); - if ( PNM_FORMAT_TYPE(format1) != format3 || - PNM_FORMAT_TYPE(format2) != format3 ) - { - switch ( PNM_FORMAT_TYPE(format3) ) - { - case PPM_TYPE: - if ( PNM_FORMAT_TYPE(format1) != format3 ) - pm_message( "promoting first file to PPM" ); - if ( PNM_FORMAT_TYPE(format2) != format3 ) - pm_message( "promoting second file to PPM" ); - break; - case PGM_TYPE: - if ( PNM_FORMAT_TYPE(format1) != format3 ) - pm_message( "promoting first file to PGM" ); - if ( PNM_FORMAT_TYPE(format2) != format3 ) - pm_message( "promoting second file to PGM" ); - break; - } - } - pnm_writepnminit( stdout, cols1, rows1, maxval3, format3, 0 ); - for ( row = 0; row < rows1; ++row ) + if (replicate1) + { pnm_readpnmrow(ifp1,xelrow1,1,maxval1,format1); + if ((maxval1 != maxval3) || (PNM_FORMAT_TYPE(format1) != format3)) + { pnm_promoteformatrow(xelrow1,1,maxval1,format1,maxval3,format3); + } + } + if (replicate2) + { pnm_readpnmrow(ifp2,xelrow2,1,maxval2,format2); + if ((maxval2 != maxval3) || (PNM_FORMAT_TYPE(format2) != format3)) + { pnm_promoteformatrow(xelrow2,1,maxval2,format2,maxval3,format3); + } + } + + pnm_writepnminit( stdout, ocols, orows, maxval3, format3, 0 ); + for ( row = 0; row < orows; ++row ) { - pnm_readpnmrow( ifp1, xelrow1, cols1, maxval1, format1 ); - if ( maxval1 != maxval3 || PNM_FORMAT_TYPE(format1) != format3 ) - pnm_promoteformatrow( - xelrow1, cols1, maxval1, format1, maxval3, format3 ); - - pnm_readpnmrow( ifp2, xelrow2, cols1, maxval2, format2 ); - if ( maxval2 != maxval3 || PNM_FORMAT_TYPE(format2) != format3 ) - pnm_promoteformatrow( - xelrow2, cols1, maxval2, format2, maxval3, format3 ); + if (! replicate1) + { pnm_readpnmrow(ifp1,xelrow1,cols1,maxval1,format1); + if ((maxval1 != maxval3) || (PNM_FORMAT_TYPE(format1) != format3)) + { pnm_promoteformatrow(xelrow1,cols1,maxval1,format1,maxval3,format3); + } + } + if (! replicate2) + { pnm_readpnmrow(ifp2,xelrow2,cols2,maxval2,format2); + if ((maxval2 != maxval3) || (PNM_FORMAT_TYPE(format2) != format3)) + { pnm_promoteformatrow(xelrow2,cols2,maxval2,format2,maxval3,format3); + } + } - for ( col = 0, x1P = xelrow1, x2P = xelrow2; - col < cols1; ++col, ++x1P, ++x2P ) + for ( col = 0, x1P = xelrow1, x2P = xelrow2, oxp = oxelrow; + col < ocols; ++col, (replicate1||++x1P), (replicate2||++x2P), oxp++ ) { switch ( PNM_FORMAT_TYPE(format3) ) { @@ -147,9 +168,9 @@ break; case '*': - r1 = r1 * r2 / maxval3; - g1 = g1 * g2 / maxval3; - b1 = b1 * b2 / maxval3; + r1 = (unsigned int)r1 * (unsigned int)r2 / (unsigned int)maxval3; + g1 = (unsigned int)g1 * (unsigned int)g2 / (unsigned int)maxval3; + b1 = (unsigned int)b1 * (unsigned int)b2 / (unsigned int)maxval3; break; case 'D': @@ -163,13 +184,19 @@ g1 = (g1>g2)?(g2):(g1); b1 = (b1>b2)?(b2):(b1); break; - + case 'X': r1 = (r1>r2)?(r1):(r2); g1 = (g1>g2)?(g1):(g2); b1 = (b1>b2)?(b1):(b2); break; + case 'V': + r1 = (r1 + r2) / 2; + g1 = (g1 + g2) / 2; + b1 = (b1 + b2) / 2; + break; + default: pm_error( "can't happen" ); } @@ -179,7 +206,7 @@ else if ( g1 > maxval3 ) g1 = maxval3; if ( b1 < 0 ) b1 = 0; else if ( b1 > maxval3 ) b1 = maxval3; - PPM_ASSIGN( *x1P, r1, g1, b1 ); + PPM_ASSIGN( *oxp, r1, g1, b1 ); } break; @@ -210,22 +237,26 @@ case 'N': g1 = (g1>g2)?(g2):(g1); break; - + case 'X': g1 = (g1>g2)?(g1):(g2); break; + case 'V': + g1 = (g1 + g2) / 2; + break; + default: pm_error( "can't happen" ); } if ( g1 < 0 ) g1 = 0; else if ( g1 > maxval3 ) g1 = maxval3; - PNM_ASSIGN1( *x1P, g1 ); + PNM_ASSIGN1( *oxp, g1 ); } break; } } - pnm_writepnmrow( stdout, xelrow1, cols1, maxval3, format3, 0 ); + pnm_writepnmrow( stdout, oxelrow, ocols, maxval3, format3, 0 ); } pm_close( ifp1 );