/* * libpipi Proper image processing implementation library * Copyright (c) 2004-2008 Sam Hocevar * All Rights Reserved * * $Id$ * * This library is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it * and/or modify it under the terms of the Do What The Fuck You Want * To Public License, Version 2, as published by Sam Hocevar. See * http://sam.zoy.org/wtfpl/COPYING for more details. */ /* * resize.c: image resizing functions */ #include "config.h" #include "common.h" #include #include #include "pipi.h" #include "pipi_internals.h" pipi_image_t *pipi_resize(pipi_image_t *src, int w, int h) { float *srcdata, *dstdata, *aline, *line; pipi_image_t *dst; pipi_pixels_t *srcp, *dstp; int x, y, x0, y0, sw, dw, sh, dh, remy; srcp = pipi_getpixels(src, PIPI_PIXELS_RGBA_F); srcdata = (float *)srcp->pixels; dst = pipi_new(w, h); dstp = pipi_getpixels(dst, PIPI_PIXELS_RGBA_F); dstdata = (float *)dstp->pixels; sw = src->w; sh = src->h; dw = dst->w; dh = dst->h; aline = malloc(3 * dw * sizeof(float)); line = malloc(3 * dw * sizeof(float)); memset(line, 0, 3 * dw * sizeof(float)); remy = 0; for(y = 0, y0 = 0; y < dh; y++) { int toty = 0, ny; memset(aline, 0, 3 * dw * sizeof(float)); while(toty < sh) { if(remy == 0) { float r = 0, g = 0, b = 0; int remx = 0; for(x = 0, x0 = 0; x < dw; x++) { float ar = 0, ag = 0, ab = 0; int totx = 0, nx; while(totx < sw) { if(remx == 0) { r = srcdata[(y0 * sw + x0) * 4]; g = srcdata[(y0 * sw + x0) * 4 + 1]; b = srcdata[(y0 * sw + x0) * 4 + 2]; x0++; remx = dw; } nx = (totx + remx <= sw) ? remx : sw - totx; ar += nx * r; ag += nx * g; ab += nx * b; totx += nx; remx -= nx; } line[3 * x] = ar; line[3 * x + 1] = ag; line[3 * x + 2] = ab; } y0++; remy = dh; } ny = (toty + remy <= sh) ? remy : sh - toty; for(x = 0; x < dw; x++) { aline[3 * x] += ny * line[3 * x]; aline[3 * x + 1] += ny * line[3 * x + 1]; aline[3 * x + 2] += ny * line[3 * x + 2]; } toty += ny; remy -= ny; } for(x = 0; x < dw; x++) { dstdata[(y * dw + x) * 4] = aline[3 * x] / (sw * sh); dstdata[(y * dw + x) * 4 + 1] = aline[3 * x + 1] / (sw * sh); dstdata[(y * dw + x) * 4 + 2] = aline[3 * x + 2] / (sw * sh); } } free(aline); free(line); return dst; }