template<class _mm,bool chroma,bool avih,bool uniform> void TimgFilterNoise::addNoise(const unsigned char *src,stride_t srcStride,unsigned char *dst,stride_t dstStride,unsigned int dx,unsigned int dy,short *noiseMask,stride_t noiseMaskStride,int noiseStrength)
{
    typename _mm::__m noisenext64;
    if (!avih) {
        noisenext64=Tnoise<_mm>::noisenext();
    }
    typename _mm::__m noiseStrength64=_mm::set1_pi16((short)noiseStrength);
    typename _mm::__m m0=_mm::setzero_si64(),m255=_mm::set1_pi16(255),m128=_mm::set1_pi16(128);
    for (const unsigned char *srcEnd=src+srcStride*dy; src!=srcEnd; src+=srcStride,dst+=dstStride,noiseMask+=noiseMaskStride) {
        int x=0;
        for (; x<int(dx-_mm::size/2+1); x+=_mm::size/2) {
            typename _mm::__m noise;
            if (!avih) {
                noise=noisenext64=_mm::add_pi16(_mm::madd_pi16(noisenext64,Tnoise<_mm>::noiseConst()),Tnoise<_mm>::noiseConst());
                noise=_mm::subs_pi16(_mm::and_si64(noise,m255),m128);
            } else {
                movVqu(noise, noiseMask+x);    //SSE3
            }
            typename _mm::__m noiseMul,src8=_mm::unpacklo_pi8(_mm::load2(src+x),m0);
            if (uniform) {
                noiseMul=noise;
            } else {
                noiseMul=src8;
                if (chroma) {
                    noiseMul=_mm::subs_pi16(noiseMul,m128);
                    noiseMul=_mm::slli_pi16(noiseMul,3);
                }
                noiseMul=_mm::srai_pi16(_mm::mullo_pi16(noiseMul,noise),8);
            }
            if (!avih) {
                movVqu(noiseMask+x,noiseMul=_mm::srai_pi16(_mm::mullo_pi16(noiseMul,noiseStrength64),8));
            }
            _mm::store2(dst+x,_mm::packs_pu16(_mm::add_pi16(noiseMul,src8),m0));
        }
        for (; x<(int)dx; x++) {
            int mm1;
            if (!avih) {
                typename _mm::integer2_t val;
                _mm::store2(&val,noisenext64=_mm::add_pi16(_mm::madd_pi16(noisenext64,Tnoise<_mm>::noiseConst()),Tnoise<_mm>::noiseConst()));
                mm1=(char)val;
            } else {
                mm1=(char)noiseMask[x];
            }
            int mm0,mm7=src[x];
            if (uniform) {
                mm0=mm1;
            } else {
                mm0=mm7;
                if (chroma) {
                    mm0-=128;
                }
                mm0=(mm0*mm1)>>8;
            }
            if (!avih) {
                noiseMask[x]=(short)(mm0=(mm0*noiseStrength)>>8);
            }
            dst[x]=limit_uint8(mm0+mm7);
        }
    }
Beispiel #2
0
LRESULT TlevelsPage::TwidgetCurves::onLbuttonDown(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    if (curpoint==-1 && pt.size()<10) {
        int x=GET_X_LPARAM(lParam),y=GET_Y_LPARAM(lParam);
        x=limit_uint8(256*x/dxy);
        CPoints::iterator p=pt.begin();
        for (pt.begin(); p!=pt.end()-1; p++)
            if ((p+1)->x>x) {
                break;
            }
        p=pt.insert(p+1,CPoint(x,limit_uint8(255-256*y/dxy)));
        save();
        curpoint=int(p-pt.begin());
        levelsPage->map2dlg();//InvalidateRect(hwnd,NULL,FALSE);
    }
    SetCapture(hwnd);
    SetCursor(LoadCursor(NULL,IDC_SIZEALL));
    dragpoint=curpoint;
    print();
    return 0;
}
Beispiel #3
0
void TlevelsPage::onCurveLoad(void)
{
    if (dlgGetFile(false,m_hwnd,_(-IDD_LEVELS,_l("Select curve file")),_l("Adobe Photoshop Curves (*.acv)\0*.acv\0All files (*.*)\0*.*\0"),_l("acv"),curvesflnm,_l("."),0)) {
        FILE *f=fopen(curvesflnm,_l("rb"));
        if (!f) {
            return;
        }
        int16_t w;
        if (fread(&w,1,2,f)==2 && av_be2ne16(w)==4)
            if (fread(&w,1,2,f)==2 && av_be2ne16(w)==5) {
                int16_t cnt;
                if (fread(&cnt,1,2,f)==2 && (cnt=av_be2ne16(cnt))>0) {
                    cnt=std::min(cnt,int16_t(10));
                    cfgSet(IDFF_levelsNumPoints,cnt);
                    std::pair<uint8_t,uint8_t> pts[10];
                    int numpoints=0;
                    for (int i=0; i<cnt; i++) {
                        int16_t x,y;
                        if (fread(&y,1,2,f)!=2 || fread(&x,1,2,f)!=2) {
                            break;
                        }
                        pts[numpoints].first=limit_uint8(av_be2ne16(x));
                        pts[numpoints].second=limit_uint8(av_be2ne16(y));
                        numpoints++;
                    }
                    std::sort(pts,pts+numpoints);
                    for (int i=0; i<numpoints; i++) {
                        cfgSet(TwidgetCurves::idffs[2*i+0],pts[i].first);
                        cfgSet(TwidgetCurves::idffs[2*i+1],pts[i].second);
                    }
                    wCurves->reset();
                    map2dlg();
                }
            }
        fclose(f);
    }
}
Beispiel #4
0
LRESULT TlevelsPage::TwidgetCurves::onMouseMove(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    if (dragpoint!=-1) {
        int x=256*GET_X_LPARAM(lParam)/dxy;
        int y=255-256*GET_Y_LPARAM(lParam)/dxy;
        static const int border=40;
        if (pt.size()>2 && (!isIn(x,0-border,255+border) || !isIn(y,0-border,255+border))) {
            pt.erase(pt.begin()+curpoint);
            curpoint=-1;
            onLbuttonUp(hwnd,uMsg,wParam,lParam);
        } else {
            pt[dragpoint].x=limit(x,int(dragpoint==0?0:pt[dragpoint-1].x),int(dragpoint==(int)pt.size()-1?255:pt[dragpoint+1].x));
            pt[dragpoint].y=limit_uint8(y);
        }
        save();
        levelsPage->map2dlg();
        return 0;
    }
    return TwindowWidget::onMouseMove(hwnd,uMsg,wParam,lParam);
}
Beispiel #5
0
void TlevelsSettings::plot_curve(int p1, int p2, int p3, int p4, unsigned int curve[256])
{
    typedef double CRMatrix[4][4];
    static const CRMatrix CR_basis = {
        { -0.5,  1.5, -1.5,  0.5 },
        {  1.0, -2.5,  2.0, -0.5 },
        { -0.5,  0.0,  0.5,  0.0 },
        {  0.0,  1.0,  0.0,  0.0 },
    };
    struct curves_CR_compose {
        void operator()(const CRMatrix &a, const CRMatrix &b, CRMatrix &ab) {
            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 4; j++)
                    ab[i][j] = (a[i][0] * b[0][j] +
                                a[i][1] * b[1][j] +
                                a[i][2] * b[2][j] +
                                a[i][3] * b[3][j]);
        }
    };

    CRMatrix geometry;
    CRMatrix tmp1, tmp2;
    CRMatrix deltas;
    double  x, dx, dx2, dx3;
    double  y, dy, dy2, dy3;
    double  d, d2, d3;
    int     lastx, lasty;
    int   newx, newy;
    int     i;

    /* construct the geometry matrix from the segment */
    for (i = 0; i < 4; i++) {
        geometry[i][2] = 0;
        geometry[i][3] = 0;
    }

    for (i = 0; i < 2; i++) {
        geometry[0][i] = this->*points[p1][i];
        geometry[1][i] = this->*points[p2][i];
        geometry[2][i] = this->*points[p3][i];
        geometry[3][i] = this->*points[p4][i];
    }

    /* subdivide the curve */
    static const int CURVES_SUBDIVIDE = 1000;

    d = 1.0 / CURVES_SUBDIVIDE;
    d2 = d * d;
    d3 = d * d * d;

    /* construct a temporary matrix for determining the forward
     * differencing deltas
     */
    tmp2[0][0] = 0;
    tmp2[0][1] = 0;
    tmp2[0][2] = 0;
    tmp2[0][3] = 1;
    tmp2[1][0] = d3;
    tmp2[1][1] = d2;
    tmp2[1][2] = d;
    tmp2[1][3] = 0;
    tmp2[2][0] = 6 * d3;
    tmp2[2][1] = 2 * d2;
    tmp2[2][2] = 0;
    tmp2[2][3] = 0;
    tmp2[3][0] = 6 * d3;
    tmp2[3][1] = 0;
    tmp2[3][2] = 0;
    tmp2[3][3] = 0;

    /* compose the basis and geometry matrices */
    curves_CR_compose()(CR_basis, geometry, tmp1);

    /* compose the above results to get the deltas matrix */
    curves_CR_compose()(tmp2, tmp1, deltas);

    /* extract the x deltas */
    x   = deltas[0][0];
    dx  = deltas[1][0];
    dx2 = deltas[2][0];
    dx3 = deltas[3][0];

    /* extract the y deltas */
    y   = deltas[0][1];
    dy  = deltas[1][1];
    dy2 = deltas[2][1];
    dy3 = deltas[3][1];

    lastx = limit_uint8((int)x);
    lasty = limit_uint8((int)y);

    curve[lastx] = lasty;

    /* loop over the curve */
    for (i = 0; i < CURVES_SUBDIVIDE; i++) {
        /* increment the x values */
        x += dx;
        dx += dx2;
        dx2 += dx3;

        /* increment the y values */
        y += dy;
        dy += dy2;
        dy2 += dy3;

        newx = limit_uint8(int (x));
        newy = limit_uint8(int (y));

        /* if this point is different than the last one...then draw it */
        if ((lastx != newx) || (lasty != newy)) {
            curve[newx] = newy;
        }

        lastx = newx;
        lasty = newy;
    }
}