⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resample.c

📁 M8手机图片查看器
💻 C
📖 第 1 页 / 共 2 页
字号:

    DWORD * tb;        // Temporary (intermediate buffer)


    double intensity[COLOR_COMPONENTS];	// RGBA component intensities

    double center;				// Center of current sampling
    double weight;				// Current wight
    LONG left;						// Left of current sampling
    LONG right;						// Right of current sampling

    double * p_weight;		// Temporary pointer
    LONG   * p_pixel;     // Temporary pointer

    LONG MAX_CONTRIBS;    // Almost-const: max number of contribution for current sampling
    double SCALED_RADIUS;	// Almost-const: scaled radius for downsampling operations
    double FILTER_FACTOR; // Almost-const: filter factor for downsampling operations

    /* Preliminary (redundant ? ) check */
    if (iw < 1 || ih < 1 || ibuf == NULL || ow < 1 || oh < 1 || obuf == NULL) {
        return FALSE;
    }

    /* Aliasing buffers */
    ib = (DWORD *)ibuf;
    ob = (DWORD *)obuf;

    if (ow == iw && oh == ih) { /* Aame size, no resampling */
        CopyMemory(ob, ib, iw * ih * sizeof(COLORREF));
        return TRUE;
    }

    xScale = ((double)ow / iw);
    yScale = ((double)oh / ih);

    h_weight = NULL;
    h_pixel  = NULL;
    h_count  = NULL;
    h_wsum   = NULL;

    v_weight = NULL;
    v_pixel  = NULL;
    v_count  = NULL;
    v_wsum   = NULL;


    tb = NULL;

    tb = (DWORD *) GlobalAlloc(0,  ow * ih * sizeof(DWORD));

    if (! tb) goto Cleanup;

    if (xScale > 1.0) {
        /* Horizontal upsampling */
        FILTER_FACTOR = 1.0;
        SCALED_RADIUS = dRadius;
    } else { /* Horizontal downsampling */
        FILTER_FACTOR = xScale;
        SCALED_RADIUS = dRadius / xScale;
    }
    /* The maximum number of contributions for a target pixel */
    MAX_CONTRIBS  = (int)(2 * SCALED_RADIUS  + 1);

    /* Pre-allocating all of the needed memory */
    h_weight = (double *) GlobalAlloc(0, ow * MAX_CONTRIBS * sizeof(double));  /* weights */
    h_pixel  = (int *) GlobalAlloc(0, ow * MAX_CONTRIBS * sizeof(int));  /* the contributing pixels */
    h_count  = (int *) GlobalAlloc(0, ow * sizeof(int));  /* how may contributions for the target pixel */
    h_wsum   = (double *)GlobalAlloc(0, ow * sizeof(double));  /* sum of the weights for the target pixel */

    if (!(h_weight && h_pixel || h_count || h_wsum)) goto Cleanup;

    /* Pre-calculate weights contribution for a row */
    for (i = 0; i < ow; i++) {
        p_weight    = h_weight + i * MAX_CONTRIBS;
        p_pixel     = h_pixel  + i * MAX_CONTRIBS;

        h_count[i] = 0;
        h_wsum[i] =  0.0;

        center = ((double)i) / xScale;
        left = (int)((center + .5) - SCALED_RADIUS);
        right = (int)(left + 2 * SCALED_RADIUS);

        for (j = left; j <= right; j++) {
            if (j < 0 || j >= iw) continue;

            weight = (*pFnFilter)((center - j) * FILTER_FACTOR);

            if (weight == 0.0) continue;

            n = h_count[i]; /* Since h_count[i] is our current index */
            p_pixel[n] = j;
            p_weight[n] = weight;
            h_wsum[i] += weight;
            h_count[i]++; /* Increment contribution count */
        }/* j */
    }/* i */

    /* Filter horizontally from input to temporary buffer */
    for (n = 0; n < ih; n++) {
        /* Here 'n' runs on the vertical coordinate */
        for (i = 0; i < ow; i++) {/* i runs on the horizontal coordinate */
            p_weight = h_weight + i * MAX_CONTRIBS;
            p_pixel  = h_pixel  + i * MAX_CONTRIBS;

            for (c = 0; c < COLOR_COMPONENTS; c++) {
                intensity[c] = 0.0;
            }
            for (j = 0; j < h_count[i]; j++) {
                weight = p_weight[j];
                val = ib[p_pixel[j] + n * iw]; /* Using val as temporary storage */
                /* Acting on color components */
                for (c = 0; c < COLOR_COMPONENTS; c++) {
                    intensity[c] += (val & 0xFF) * weight;
                    val = val >> 8;
                }
            }
            /* val is already 0 */
            for (c = 0 ; c < COLOR_COMPONENTS; c++) {
                val = val << 8;
                col = (int)(intensity[COLOR_COMPONENTS - c - 1] / h_wsum[i]);
                if (col < 0) col = 0;
                if (col > 255) col = 255;
                val |= col;
            }
            tb[i+n*ow] = val; /* Temporary buffer ow x ih */
        }/* i */
    }/* n */

    /* Going to vertical stuff */
    if (yScale > 1.0) {
        FILTER_FACTOR = 1.0;
        SCALED_RADIUS = dRadius;
    } else {
        FILTER_FACTOR = yScale;
        SCALED_RADIUS = dRadius / yScale;
    }
    MAX_CONTRIBS  = (int)(2 * SCALED_RADIUS  + 1);

    /* Pre-calculate filter contributions for a column */
    v_weight = (double *) GlobalAlloc(0, oh * MAX_CONTRIBS * sizeof(double));  /* Weights */
    v_pixel  = (int *) GlobalAlloc(0, oh * MAX_CONTRIBS * sizeof(int));  /* The contributing pixels */
    v_count  = (int *) GlobalAlloc(0, oh * sizeof(int));  /* How may contributions for the target pixel */
    v_wsum   = (double *)GlobalAlloc(0, oh * sizeof(double));  /* Sum of the weights for the target pixel */

    if (!(v_weight && v_pixel && v_count && v_wsum)) goto Cleanup;

    for (i = 0; i < oh; i++) {
        p_weight = v_weight + i * MAX_CONTRIBS;
        p_pixel  = v_pixel  + i * MAX_CONTRIBS;

        v_count[i] = 0;
        v_wsum[i] = 0.0;

        center = ((double) i) / yScale;
        left = (int)(center + .5 - SCALED_RADIUS);
        right = (int)(left + 2 * SCALED_RADIUS);

        for (j = left; j <= right; j++) {
            if (j < 0 || j >= ih) continue;

            weight = (*pFnFilter)((center - j) * FILTER_FACTOR);

            if (weight == 0.0) continue;
            n = v_count[i]; /* Our current index */
            p_pixel[n] = j;
            p_weight[n] = weight;
            v_wsum[i] += weight;
            v_count[i]++; /* Increment the contribution count */
        }/* j */
    }/* i */

    /* Filter vertically from work to output */
    for (n = 0; n < ow; n++) {
        for (i = 0; i < oh; i++) {
            p_weight = v_weight + i * MAX_CONTRIBS;
            p_pixel     = v_pixel  + i * MAX_CONTRIBS;

            for (c = 0; c < COLOR_COMPONENTS; c++) {
                intensity[c] = 0.0;
            }

            for (j = 0; j < v_count[i]; j++) {
                weight = p_weight[j];
                val = tb[ n + ow * p_pixel[j]]; /* Using val as temporary storage */
                /* Acting on color components */
                for (c = 0; c < COLOR_COMPONENTS; c++) {
                    intensity[c] += (val & 0xFF) * weight;
                    val = val >> 8;
                }
            }
            /* val is already 0 */
            for (c = 0; c < COLOR_COMPONENTS; c++) {
                val = val << 8;
                col = (int)(intensity[COLOR_COMPONENTS - c - 1] / v_wsum[i]);
                if (col < 0) col = 0;
                if (col > 255) col = 255;
                val |= col;
            }
            ob[n+i*ow] = val;
        }/* i */
    }/* n */

    fSuccess = TRUE;

Cleanup: /* CLEANUP */

    if (tb) GlobalFree(tb);

    if (h_weight) GlobalFree(h_weight);
    if (h_pixel) GlobalFree(h_pixel);
    if (h_count) GlobalFree(h_count);
    if (h_wsum) GlobalFree(h_wsum);

    if (v_weight) GlobalFree(v_weight);
    if (v_pixel) GlobalFree(v_pixel);
    if (v_count) GlobalFree(v_count);
    if (v_wsum) GlobalFree(v_wsum);

    return fSuccess;
} /* _resample */




/* _fillBITMAPINFO helper function
  fills a BITMAPINFO struct given a HBITMAP
	ARGS:
	hBmp [IN] handle of the bitmap
	pBinfo [INOUT] pointer to a valid BITMAPINFO struct
	RETURN VALUE:
	TRUE on success
*/
BOOL _fillBITMAPINFO(HBITMAP hBmp, BITMAPINFO * pBinfo) {
    BITMAP bmp;

    ZeroMemory(& bmp, sizeof(bmp));

    if (! GetObject(hBmp, sizeof(BITMAP), &bmp)) {
        return FALSE;
    }
    if (bmp.bmPlanes != 1 || bmp.bmBitsPixel < 24) {
        return FALSE;
    }

    /* Getting info about the source bitmap
    */
    ZeroMemory(pBinfo, sizeof(*pBinfo));

    pBinfo->bmiHeader.biSize = sizeof(pBinfo->bmiHeader);
    pBinfo->bmiHeader.biWidth = bmp.bmWidth;
    pBinfo->bmiHeader.biHeight = bmp.bmHeight;
    pBinfo->bmiHeader.biBitCount = bmp.bmBitsPixel;
    pBinfo->bmiHeader.biPlanes = 1;
    pBinfo->bmiHeader.biCompression = BI_RGB;
    pBinfo->bmiHeader.biSizeImage    = bmp.bmBitsPixel * bmp.bmWidth * bmp.bmHeight / 8;

    return TRUE;
}



/* Lanczos8 filter, default radius 8
*/
double _Lanczos8(double x) {
    const double R = 8.0;
    if (x  < 0.0) x = - x;

    if (x == 0.0) return 1;

    if (x < R) {
        x *= M_PI;
        return R * sin(x) * sin(x / R) / (x*x);
    }
    return 0.0;
}


/* Lanczos3 filter, default radius 3
*/
double _Lanczos3(double x) {
    const double R = 3.0;
    if (x  < 0.0) x = - x;

    if (x == 0.0) return 1;

    if (x < R) {
        x *= M_PI;
        return R * sin(x) * sin(x / R) / (x*x);
    }
    return 0.0;
}

/* Hermite filter, default radius 1
*/
double _Hermite(double x) {
    if (x < 0.0) x = - x;

    if (x < 1.0) return ((2.0 * x - 3) * x * x + 1.0);

    return 0.0;
}

/* Box filter, default radius 0.5
*/
double _Box(double x) {
    if (x < 0.0) x = - x;

    if (x <= 0.5) return 1.0;

    return 0.0;
}


/* Trangle filter, default radius 1
*/
double _Triangle(double x) {
    if (x < 0.0) x = - x;
    if (x < 1.0) return (1.0 - x);
    return 0.0;
}

/* Bell filter, default radius 1.5
*/
double _Bell(double x) {
    if (x < 0.0) x = - x;
    if (x < 0.5) return (0.75 - x*x);
    if (x < 1.5) return (0.5 * pow(x - 1.5, 2.0));
    return 0.0;
}

/* CubicSpline filter, default radius 2
*/
double _CubicSpline(double x) {
    double x2;

    if (x < 0.0) x = - x;
    if (x < 1.0) {
        x2 = x * x;
        return (0.5 * x2 * x - x2 + 2.0 / 3.0);
    }
    if (x < 2.0) {
        x = 2.0 - x;
        return (pow(x, 3.0) / 6.0);
    }
    return 0;
}


/* Mitchell filter, default radius 2.0
*/
double _Mitchell(double x) {
    const double C = 1.0 / 3.0;
    double x2;

    if (x < 0.0) x = - x;
    x2 = x * x;
    if (x < 1.0) {
        x = (((12.0 - 9.0 * C - 6.0 * C) * (x * x2)) + ((-18.0 + 12.0 * C + 6.0 * C) * x2) + (6.0 - 2.0 * C));
        return (x / 6.0);
    }
    if (x < 2.0) {
        x = (((-C - 6.0 * C) * (x * x2)) + ((6.0 * C + 30.0 * C) * x2) + ((-12.0 * C - 48.0 * C) * x) + (8.0 * C + 24.0 * C));
        return (x / 6.0);
    }
    return 0.0;
}

/* Cosine filter, default radius 1
*/
double _Cosine(double x) {
    if ((x >= -1.0) && (x <= 1.0)) return ((cos(x * M_PI) + 1.0) / 2.0);

    return 0;
}

/* CatmullRom filter, default radius 2
*/
double _CatmullRom(double x) {
    const double C = 0.5;
    double x2;
    if (x < 0.0) x = - x;
    x2 = x * x;

    if (x <= 1.0) return (1.5 * x2 * x - 2.5 * x2 + 1);
    if (x <= 2.0) return (- 0.5 * x2 * x + 2.5 * x2 - 4 * x + 2);
    return 0;
}

/* Quadratic filter, default radius 1.5
*/
double _Quadratic(double x) {
    if (x < 0.0) x = - x;
    if (x <= 0.5) return (- 2.0 * x * x + 1);
    if (x <= 1.5) return (x * x - 2.5* x + 1.5);
    return 0.0;
}

/* QuadraticBSpline filter, default radius 1.5
*/
double _QuadraticBSpline(double x) {
    if (x < 0.0) x = - x;
    if (x <= 0.5) return (- x * x + 0.75);
    if (x <= 1.5) return (0.5 * x * x - 1.5 * x + 1.125);
    return 0.0;
}
/* CubicConvolution filter, default radius 3
*/
double _CubicConvolution(double x) {
    double x2;
    if (x < 0.0) x = - x;
    x2 = x * x;
    if (x <= 1.0) return ((4.0 / 3.0)* x2 * x - (7.0 / 3.0) * x2 + 1.0);
    if (x <= 2.0) return (- (7.0 / 12.0) * x2 * x + 3 * x2 - (59.0 / 12.0) * x + 2.5);
    if (x <= 3.0) return ((1.0 / 12.0) * x2 * x - (2.0 / 3.0) * x2 + 1.75 * x - 1.5);
    return 0;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -