IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 26, 2009, 8:40:07 PM (17 years ago)
Author:
eugene
Message:

incorporating changes from 16bit mask upgrades (eam_branch_20081230)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/imageops/psImageConvolve.c

    r20830 r21183  
    77/// @author Eugene Magnier, IfA
    88///
    9 /// @version $Revision: 1.81 $ $Name: not supported by cvs2svn $
    10 /// @date $Date: 2008-11-26 00:43:12 $
     9/// @version $Revision: 1.82 $ $Name: not supported by cvs2svn $
     10/// @date $Date: 2009-01-27 06:39:37 $
    1111///
    1212/// Copyright 2004-2007 Institute for Astronomy, University of Hawaii
     
    319319}
    320320
    321 psImage *psImageConvolveMaskDirect(psImage *out, const psImage *mask, psMaskType maskVal,
    322                                    psMaskType setVal, int xMin, int xMax, int yMin, int yMax)
     321psImage *psImageConvolveMaskDirect(psImage *out, const psImage *mask, psImageMaskType maskVal,
     322                                   psImageMaskType setVal, int xMin, int xMax, int yMin, int yMax)
    323323{
    324324    PS_ASSERT_IMAGE_NON_NULL(mask, NULL);
    325     PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, NULL);
     325    PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_IMAGE_MASK, NULL);
    326326    if (out == mask && ((maskVal & setVal) || !setVal)) {
    327327        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     
    352352    if (!out) {
    353353        // Propagate the non-masked values
    354         out = (psImage*)psBinaryOp(NULL, (const psPtr)mask, "&", psScalarAlloc(~maskVal, PS_TYPE_MASK));
     354        out = (psImage*)psBinaryOp(NULL, (const psPtr)mask, "&", psScalarAlloc(~maskVal, PS_TYPE_IMAGE_MASK));
    355355    }
    356356
    357357    // Dereference mask images
    358     psMaskType **maskData = mask->data.PS_TYPE_MASK_DATA;
    359     psMaskType **outData = out->data.PS_TYPE_MASK_DATA;
     358    psImageMaskType **maskData = mask->data.PS_TYPE_IMAGE_MASK_DATA;
     359    psImageMaskType **outData = out->data.PS_TYPE_IMAGE_MASK_DATA;
    360360
    361361    if (setVal) {
     
    376376        for (int row = 0; row < numRows; row++) {
    377377            for (int col = 0; col < numCols; col++) {
    378                 psMaskType pixel = outData[row][col]; // Pixel value to set
     378                psImageMaskType pixel = outData[row][col]; // Pixel value to set
    379379                if (pixel & maskVal) {
    380380                    // Already done this one
     
    395395
    396396
    397 psImage *psImageConvolveMaskFFT(psImage *out, const psImage *mask, psMaskType maskVal,
    398                                 psMaskType setVal, int xMin, int xMax, int yMin, int yMax, float thresh)
     397psImage *psImageConvolveMaskFFT(psImage *out, const psImage *mask, psImageMaskType maskVal,
     398                                psImageMaskType setVal, int xMin, int xMax, int yMin, int yMax, float thresh)
    399399{
    400400    PS_ASSERT_IMAGE_NON_NULL(mask, NULL);
    401     PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, NULL);
     401    PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_IMAGE_MASK, NULL);
    402402    PS_ASSERT_FLOAT_LARGER_THAN(thresh, 0.0, NULL);
    403403    PS_ASSERT_FLOAT_LESS_THAN(thresh, 1.0, NULL);
     
    431431    for (int y = 0; y < numRows; y++) {
    432432        for (int x = 0; x < numCols; x++) {
    433             if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) {
     433            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) {
    434434                onoff->data.F32[y][x] = 1.0;
    435435            }
     
    452452
    453453    if (!out) {
    454         out = psImageAlloc(numCols, numRows, PS_TYPE_MASK);
     454        out = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK);
    455455    }
    456456    for (int y = 0; y < numRows; y++) {
    457457        for (int x = 0; x < numCols; x++) {
    458             out->data.PS_TYPE_MASK_DATA[y][x] = (convolved->data.F32[y][x] >= thresh) ?
    459                 (mask->data.PS_TYPE_MASK_DATA[y][x] | setVal) : mask->data.PS_TYPE_MASK_DATA[y][x];
     458            out->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = (convolved->data.F32[y][x] >= thresh) ?
     459                (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] | setVal) : mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x];
    460460        }
    461461    }
     
    651651case PS_TYPE_##TYPE: { \
    652652    psImage *calculation = psImageAlloc(numRows, numCols, PS_TYPE_##TYPE); /* Calculation image; BW */ \
    653     psImage *calcMask = psImageAlloc(numRows, numCols, PS_TYPE_MASK); /* Mask for calculation image; BW */ \
     653    psImage *calcMask = psImageAlloc(numRows, numCols, PS_TYPE_IMAGE_MASK); /* Mask for calculation image; BW */ \
    654654    \
    655655    /** Smooth in X direction **/ \
     
    658658            int xMin = PS_MAX(i - size, 0); \
    659659            int xMax = PS_MIN(i + size, xLast); \
    660             const psMaskType *maskData = &mask->data.PS_TYPE_MASK_DATA[j][xMin]; \
     660            const psImageMaskType *maskData = &mask->data.PS_TYPE_IMAGE_MASK_DATA[j][xMin]; \
    661661            const ps##TYPE *imageData = &image->data.TYPE[j][xMin]; \
    662662            int uMin = - PS_MIN(i, size); /* Minimum kernel index */ \
     
    673673                /* BW */ \
    674674                calculation->data.TYPE[i][j] = sumIG / sumG; \
    675                 calcMask->data.PS_TYPE_MASK_DATA[i][j] = 0; \
     675                calcMask->data.PS_TYPE_IMAGE_MASK_DATA[i][j] = 0; \
    676676            } else { \
    677677                /* BW */ \
    678                 calcMask->data.PS_TYPE_MASK_DATA[i][j] = 0xFF; \
     678                calcMask->data.PS_TYPE_IMAGE_MASK_DATA[i][j] = 0xFF; \
    679679            } \
    680680        } \
     
    688688            int yMin = PS_MAX(j - size, 0); \
    689689            int yMax = PS_MIN(j + size, yLast); \
    690             const psMaskType *maskData = &calcMask->data.PS_TYPE_MASK_DATA[i][yMin]; /* BW */ \
     690            const psImageMaskType *maskData = &calcMask->data.PS_TYPE_IMAGE_MASK_DATA[i][yMin]; /* BW */ \
    691691            const ps##TYPE *imageData = &calculation->data.TYPE[i][yMin]; /* BW */ \
    692692            int vMin = - PS_MIN(j, size); /* Minimum kernel index */ \
     
    714714                           const psImage *image,
    715715                           const psImage *mask,
    716                            psMaskType maskVal,
     716                           psImageMaskType maskVal,
    717717                           float sigma,
    718718                           float numSigma,
     
    721721    PS_ASSERT_IMAGE_NON_NULL(image, NULL);
    722722    PS_ASSERT_IMAGE_NON_NULL(mask, NULL);
    723     PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, NULL);
     723    PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_IMAGE_MASK, NULL);
    724724    PS_ASSERT_IMAGES_SIZE_EQUAL(image, mask, NULL);
    725725
     
    751751      case PS_TYPE_F32: {
    752752          psImage *calculation = psImageAlloc(numRows, numCols, PS_TYPE_F32); /* Calculation image; BW */
    753           psImage *calcMask = psImageAlloc(numRows, numCols, PS_TYPE_MASK); /* Mask for calculation image; BW */
     753          psImage *calcMask = psImageAlloc(numRows, numCols, PS_TYPE_IMAGE_MASK); /* Mask for calculation image; BW */
    754754
    755755          /** Smooth in X direction **/
     
    758758                  int xMin = PS_MAX(i - size, 0);
    759759                  int xMax = PS_MIN(i + size, xLast);
    760                   const psMaskType *maskData = &mask->data.PS_TYPE_MASK_DATA[j][xMin];
     760                  const psImageMaskType *maskData = &mask->data.PS_TYPE_IMAGE_MASK_DATA[j][xMin];
    761761                  const psF32 *imageData = &image->data.F32[j][xMin];
    762762                  int uMin = - PS_MIN(i, size); /* Minimum kernel index */
     
    776776                      /* BW */
    777777                      calculation->data.F32[i][j] = sumIG / sumG;
    778                       calcMask->data.PS_TYPE_MASK_DATA[i][j] = 0;
     778                      calcMask->data.PS_TYPE_IMAGE_MASK_DATA[i][j] = 0;
    779779                  } else {
    780780                      /* BW */
    781                       calcMask->data.PS_TYPE_MASK_DATA[i][j] = 0xFF;
     781                      calcMask->data.PS_TYPE_IMAGE_MASK_DATA[i][j] = 0xFF;
    782782                  }
    783783              }
     
    791791                  int yMin = PS_MAX(j - size, 0);
    792792                  int yMax = PS_MIN(j + size, yLast);
    793                   const psMaskType *maskData = &calcMask->data.PS_TYPE_MASK_DATA[i][yMin]; /* BW */
     793                  const psImageMaskType *maskData = &calcMask->data.PS_TYPE_IMAGE_MASK_DATA[i][yMin]; /* BW */
    794794                  const psF32 *imageData = &calculation->data.F32[i][yMin]; /* BW */
    795795                  int vMin = - PS_MIN(j, size); /* Minimum kernel index */
     
    832832                                     const psImage *image,
    833833                                     const psImage *mask,
    834                                      psMaskType maskVal,
     834                                     psImageMaskType maskVal,
    835835                                     psVector *gaussNorm,
    836836                                     float minGauss,
     
    848848            int xMin = PS_MAX(i - size, 0);
    849849            int xMax = PS_MIN(i + size, xLast);
    850             const psMaskType *maskData = &mask->data.PS_TYPE_MASK_DATA[j][xMin];
     850            const psImageMaskType *maskData = &mask->data.PS_TYPE_IMAGE_MASK_DATA[j][xMin];
    851851            const psF32 *imageData = &image->data.F32[j][xMin];
    852852            int uMin = - PS_MIN(i, size); /* Minimum kernel index */
     
    863863                /* BW */
    864864                calculation->data.F32[i][j] = sumIG / sumG;
    865                 calcMask->data.PS_TYPE_MASK_DATA[i][j] = 0;
     865                calcMask->data.PS_TYPE_IMAGE_MASK_DATA[i][j] = 0;
    866866            } else {
    867867                /* BW */
    868                 calcMask->data.PS_TYPE_MASK_DATA[i][j] = 0xFF;
     868                calcMask->data.PS_TYPE_IMAGE_MASK_DATA[i][j] = 0xFF;
    869869            }
    870870        }
     
    876876                                     psImage *calculation,
    877877                                     psImage *calcMask,
    878                                      psMaskType maskVal,
     878                                     psImageMaskType maskVal,
    879879                                     psVector *gaussNorm,
    880880                                     float minGauss,
     
    892892            int yMin = PS_MAX(j - size, 0);
    893893            int yMax = PS_MIN(j + size, yLast);
    894             const psMaskType *maskData = &calcMask->data.PS_TYPE_MASK_DATA[i][yMin]; /* BW */
     894            const psImageMaskType *maskData = &calcMask->data.PS_TYPE_IMAGE_MASK_DATA[i][yMin]; /* BW */
    895895            const psF32 *imageData = &calculation->data.F32[i][yMin]; /* BW */
    896896            int vMin = - PS_MIN(j, size); /* Minimum kernel index */
     
    921921    const psImage *mask   = job->args->data[3]; // input mask
    922922
    923     psMaskType maskVal    = PS_SCALAR_VALUE(job->args->data[4],U8);
     923    psImageMaskType maskVal    = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA);
    924924    psVector *gaussNorm   = job->args->data[5]; // gauss kernel
    925925    float minGauss        = PS_SCALAR_VALUE(job->args->data[6],F32);
     
    941941    psImage *calculation  = job->args->data[1]; // calculation image
    942942    psImage *calcMask     = job->args->data[2]; // calculation mask
    943     psMaskType maskVal    = PS_SCALAR_VALUE(job->args->data[3],U8);
     943    psImageMaskType maskVal    = PS_SCALAR_VALUE(job->args->data[3],PS_TYPE_IMAGE_MASK_DATA);
    944944
    945945    psVector *gaussNorm   = job->args->data[4]; // gauss kernel
     
    956956                                    const psImage *image,
    957957                                    const psImage *mask,
    958                                     psMaskType maskVal,
     958                                    psImageMaskType maskVal,
    959959                                    float sigma,
    960960                                    float numSigma,
     
    963963    PS_ASSERT_IMAGE_NON_NULL(image, NULL);
    964964    PS_ASSERT_IMAGE_NON_NULL(mask, NULL);
    965     PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, NULL);
     965    PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_IMAGE_MASK, NULL);
    966966    PS_ASSERT_IMAGES_SIZE_EQUAL(image, mask, NULL);
    967967
     
    999999      case PS_TYPE_F32: {
    10001000          psImage *calculation = psImageAlloc(numRows, numCols, PS_TYPE_F32); /* Calculation image; BW */
    1001           psImage *calcMask = psImageAlloc(numRows, numCols, PS_TYPE_MASK); /* Mask for calculation image; BW */
     1001          psImage *calcMask = psImageAlloc(numRows, numCols, PS_TYPE_IMAGE_MASK); /* Mask for calculation image; BW */
    10021002
    10031003          /** Smooth in X direction **/
     
    10111011              psArrayAdd(job->args, 1, (psImage *) image); // cast away const
    10121012              psArrayAdd(job->args, 1, (psImage *) mask); // cast away const
    1013               PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_U8);
     1013              PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
    10141014              psArrayAdd(job->args, 1, gaussNorm);
    10151015              PS_ARRAY_ADD_SCALAR(job->args, minGauss, PS_TYPE_F32);
     
    10461046              psArrayAdd(job->args, 1, calculation);
    10471047              psArrayAdd(job->args, 1, calcMask);
    1048               PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_U8);
     1048              PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
    10491049              psArrayAdd(job->args, 1, gaussNorm);
    10501050              PS_ARRAY_ADD_SCALAR(job->args, minGauss, PS_TYPE_F32);
     
    10911091bool psImageSmoothMaskF32 (psImage *image,
    10921092                           psImage *mask,
    1093                            psMaskType maskVal,
     1093                           psImageMaskType maskVal,
    10941094                           double  sigma,
    10951095                           double  Nsigma)
     
    11221122    psVector *calculation = psVectorAlloc(Nx, PS_TYPE_F32);
    11231123    for (int j = 0; j < Ny; j++) {
    1124         psU8  *vm = mask->data.U8[j];
     1124        psImageMaskType  *vm = mask->data.PS_TYPE_IMAGE_MASK_DATA[j];
    11251125        psF32 *vi = image->data.F32[j];
    11261126        psF32 *vo = calculation->data.F32;
     
    11281128        for (int i = 0; i < Nx; i++, vi++, vo++, vm++) {
    11291129            int offset = PS_MIN (i, Nrange);
    1130             psU8  *sm = vm - offset;
     1130            psImageMaskType  *sm = vm - offset;
    11311131            psF32 *si = vi - offset;
    11321132            psF32 *sg = gauss - offset;
     
    11711171        int yMax = PS_MIN (j + Nrange + 1, Ny);
    11721172        for (int n = yMin; n < yMax; n++) {
    1173             psU8  *vm = mask->data.U8[n];
     1173            psImageMaskType  *vm = mask->data.PS_TYPE_IMAGE_MASK_DATA[n];
    11741174            psF32 *vi = image->data.F32[n];
    11751175            psF32 *vo = output->data.F32;
     
    12141214                                     const psImage *input, // Input image
    12151215                                     int start, int stop, // Range of rows
    1216                                      psMaskType maskVal, // Value to mask; NOTE subtle difference!
     1216                                     psImageMaskType maskVal, // Value to mask; NOTE subtle difference!
    12171217                                     int xMin, int xMax // Range in x for kernel
    12181218                                     )
    12191219{
    12201220    // Dereference mask images
    1221     psMaskType **inputData = input->data.PS_TYPE_MASK_DATA;
    1222     psMaskType **targetData = target->data.PS_TYPE_MASK_DATA;
     1221    psImageMaskType **inputData = input->data.PS_TYPE_IMAGE_MASK_DATA;
     1222    psImageMaskType **targetData = target->data.PS_TYPE_IMAGE_MASK_DATA;
    12231223
    12241224    int numCols = input->numCols;       // Number of columns
     
    12411241                min = PS_MAX(0, min);
    12421242                max = PS_MIN(numCols - 1, max);
    1243                 memset(&targetData[y][min], 0xff, (max - min + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
     1243                memset(&targetData[y][min], 0xff, (max - min + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_IMAGE_MASK));
    12441244            }
    12451245        }
     
    12471247            // Mask from the minimum to the end of the row
    12481248            min = PS_MAX(0, min);
    1249             memset(&targetData[y][min], 0xff, (numCols - min) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
     1249            memset(&targetData[y][min], 0xff, (numCols - min) * PSELEMTYPE_SIZEOF(PS_TYPE_IMAGE_MASK));
    12501250        }
    12511251    }
     
    12561256                                     const psImage *input, // Input image
    12571257                                     int start, int stop, // Range of rows
    1258                                      psMaskType setVal, // Value to set; NOTE subtle difference!
     1258                                     psImageMaskType setVal, // Value to set; NOTE subtle difference!
    12591259                                     int yMin, int yMax // Range in y for kernel
    12601260                                     )
    12611261{
    12621262    // Dereference mask images
    1263     psMaskType **inputData = input->data.PS_TYPE_MASK_DATA;
    1264     psMaskType **targetData = target->data.PS_TYPE_MASK_DATA;
     1263    psImageMaskType **inputData = input->data.PS_TYPE_IMAGE_MASK_DATA;
     1264    psImageMaskType **targetData = target->data.PS_TYPE_IMAGE_MASK_DATA;
    12651265
    12661266    int numRows = input->numRows;       // Number of rows
     
    13081308    int start = PS_SCALAR_VALUE(args->data[2], S32); // Row/col to start at
    13091309    int stop = PS_SCALAR_VALUE(args->data[3], S32); // Row/col to stop at
    1310     psMaskType maskVal = PS_SCALAR_VALUE(args->data[4], U8); // Value to mask/set
     1310    psImageMaskType maskVal = PS_SCALAR_VALUE(args->data[4], PS_TYPE_IMAGE_MASK_DATA); // Value to mask/set
    13111311    int kernelMin = PS_SCALAR_VALUE(args->data[5], S32); // Minimum range for kernel
    13121312    int kernelMax = PS_SCALAR_VALUE(args->data[6], S32); // Maximum range for kernel
     
    13171317}
    13181318
    1319 psImage *psImageConvolveMask(psImage *out, const psImage *mask, psMaskType maskVal,
    1320                              psMaskType setVal, int xMin, int xMax, int yMin, int yMax)
     1319psImage *psImageConvolveMask(psImage *out, const psImage *mask, psImageMaskType maskVal,
     1320                             psImageMaskType setVal, int xMin, int xMax, int yMin, int yMax)
    13211321{
    13221322    PS_ASSERT_IMAGE_NON_NULL(mask, NULL);
    1323     PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, NULL);
     1323    PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_IMAGE_MASK, NULL);
    13241324    if (out) {
    13251325        PS_ASSERT_IMAGE_NON_NULL(out, NULL);
    1326         PS_ASSERT_IMAGE_TYPE(out, PS_TYPE_MASK, NULL);
     1326        PS_ASSERT_IMAGE_TYPE(out, PS_TYPE_IMAGE_MASK, NULL);
    13271327        PS_ASSERT_IMAGES_SIZE_EQUAL(out, mask, NULL);
    13281328        if (out == mask && ((maskVal & setVal) || !setVal)) {
     
    13541354
    13551355    // Propagate the non-masked values
    1356     out = (psImage*)psBinaryOp(out, (const psPtr)mask, "&", psScalarAlloc(~setVal, PS_TYPE_MASK));
     1356    out = (psImage*)psBinaryOp(out, (const psPtr)mask, "&", psScalarAlloc(~setVal, PS_TYPE_IMAGE_MASK));
    13571357
    13581358    if (!setVal) {
     
    13601360    }
    13611361
    1362     psImage *conv = psImageAlloc(numCols, numRows, PS_TYPE_MASK); // Temporary convolved image
     1362    psImage *conv = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK); // Temporary convolved image
    13631363    psImageInit(conv, 0);
    13641364
     
    13771377            PS_ARRAY_ADD_SCALAR(job->args, start, PS_TYPE_S32);
    13781378            PS_ARRAY_ADD_SCALAR(job->args, stop, PS_TYPE_S32);
    1379             PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_MASK);
     1379            PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK);
    13801380            PS_ARRAY_ADD_SCALAR(job->args, xMin, PS_TYPE_S32);
    13811381            PS_ARRAY_ADD_SCALAR(job->args, xMax, PS_TYPE_S32);
     
    14151415            PS_ARRAY_ADD_SCALAR(job->args, start, PS_TYPE_S32);
    14161416            PS_ARRAY_ADD_SCALAR(job->args, stop, PS_TYPE_S32);
    1417             PS_ARRAY_ADD_SCALAR(job->args, setVal, PS_TYPE_MASK);
     1417            PS_ARRAY_ADD_SCALAR(job->args, setVal, PS_TYPE_IMAGE_MASK);
    14181418            PS_ARRAY_ADD_SCALAR(job->args, yMin, PS_TYPE_S32);
    14191419            PS_ARRAY_ADD_SCALAR(job->args, yMax, PS_TYPE_S32);
     
    14601460                min = PS_MAX(0, min);
    14611461                max = PS_MIN(numCols - 1, max);
    1462                 memset(&convData[y][min], 0xff, (max - min + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
     1462                memset(&convData[y][min], 0xff, (max - min + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_IMAGE_MASK));
    14631463            }
    14641464        }
     
    14661466            // Mask from the minimum to the end of the row
    14671467            min = PS_MAX(0, min);
    1468             memset(&convData[y][min], 0xff, (numCols - min) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
     1468            memset(&convData[y][min], 0xff, (numCols - min) * PSELEMTYPE_SIZEOF(PS_TYPE_IMAGE_MASK));
    14691469        }
    14701470    }
Note: See TracChangeset for help on using the changeset viewer.