image - Bicubic interpolation in C -


im trying deal bicubic image interpolation in c. therefore i've built small script.

1. "resize_image"-function:

    void resize_image(ppmimage *source_image, ppmimage *destination_image, float scale) {          uint8_t sample[3];         int y, x;          destination_image->x = (long)((float)(source_image->x)*scale);         destination_image->y = (long)((float)(source_image->y)*scale);          (y = 0; y < destination_image->y; y++) {              float v = (float)y / (float)(destination_image->y - 1);              (x = 0; x < destination_image->x; ++x) {                  float u = (float)x / (float)(destination_image->x - 1);                 sample_bicubic(source_image, u, v, sample);                  destination_image->data[x+((destination_image->y)*y)].red   = sample[0];                 destination_image->data[x+((destination_image->y)*y)].green = sample[1];                   destination_image->data[x+((destination_image->y)*y)].blue  = sample[2];               }         }     } 

2. "sample_bicubic"-function

    void sample_bicubic(ppmimage *source_image, float u, float v, uint8_t sample[]) {          float x = (u * source_image->x)-0.5;         int xint = (int)x;         float xfract = x-floor(x);          float y = (v * source_image->y) - 0.5;         int yint = (int)y;         float yfract = y - floor(y);          int i;          uint8_t p00[3];         uint8_t p10[3];         uint8_t p20[3];         uint8_t p30[3];          uint8_t p01[3];         uint8_t p11[3];         uint8_t p21[3];         uint8_t p31[3];          uint8_t p02[3];         uint8_t p12[3];         uint8_t p22[3];         uint8_t p32[3];          uint8_t p03[3];         uint8_t p13[3];         uint8_t p23[3];         uint8_t p33[3];          // 1st row         get_pixel_clamped(source_image, xint - 1, yint - 1, p00);            get_pixel_clamped(source_image, xint + 0, yint - 1, p10);         get_pixel_clamped(source_image, xint + 1, yint - 1, p20);         get_pixel_clamped(source_image, xint + 2, yint - 1, p30);          // 2nd row         get_pixel_clamped(source_image, xint - 1, yint + 0, p01);         get_pixel_clamped(source_image, xint + 0, yint + 0, p11);         get_pixel_clamped(source_image, xint + 1, yint + 0, p21);         get_pixel_clamped(source_image, xint + 2, yint + 0, p31);          // 3rd row         get_pixel_clamped(source_image, xint - 1, yint + 1, p02);         get_pixel_clamped(source_image, xint + 0, yint + 1, p12);         get_pixel_clamped(source_image, xint + 1, yint + 1, p22);         get_pixel_clamped(source_image, xint + 2, yint + 1, p32);          // 4th row         get_pixel_clamped(source_image, xint - 1, yint + 2, p03);         get_pixel_clamped(source_image, xint + 0, yint + 2, p13);         get_pixel_clamped(source_image, xint + 1, yint + 2, p23);         get_pixel_clamped(source_image, xint + 2, yint + 2, p33);          // interpolate bi-cubically!         (i = 0; < 3; i++) {              float col0 = cubic_hermite(p00[i], p10[i], p20[i], p30[i], xfract);             float col1 = cubic_hermite(p01[i], p11[i], p21[i], p31[i], xfract);             float col2 = cubic_hermite(p02[i], p12[i], p22[i], p32[i], xfract);             float col3 = cubic_hermite(p03[i], p13[i], p23[i], p33[i], xfract);              float value = cubic_hermite(col0, col1, col2, col3, yfract);              clamp(value, 0.0f, 255.0f);              sample[i] = (uint8_t)value;              printf("sample[%d]=%d\n",i,sample[i]);                }     } 

3. "interpolation helpers"

    float cubic_hermite(float a, float b, float c, float d, float t) {          float = -a / 2.0f + (3.0f*b) / 2.0f - (3.0f*c) / 2.0f + d / 2.0f;         float b = - (5.0f*b) / 2.0f + 2.0f*c - d / 2.0f;         float c = -a / 2.0f + c / 2.0f;         float d = b;          return a*t*t*t + b*t*t + c*t + d;     }      void get_pixel_clamped(ppmimage *source_image, int x, int y, uint8_t temp[])  {          clamp(x, 0, source_image->x - 1);         clamp(y, 0, source_image->y - 1);          temp[0] = source_image->data[x+(w*y)].red;         temp[1] = source_image->data[x+(w*y)].green;         temp[2] = source_image->data[x+(w*y)].blue;     } 

i've uploaded complete code stuff around here.

there no syntax errors executing code.

but output image confused me.

the input image (21x20pixel):

input image: 21x20pixel

this input image scaled 2 (42x40pixel):

output image: 42x40pixel

the interpolation seems work fine @ points, image looks pixels shifted.

can tell me i'm doing wrong? script made of: http://blog.demofox.org/2015/08/15/resizing-images-with-bicubic-interpolation/

thanks guys!

(please don't consider efficiency of code ... aweful know)

from resize_image() function:

destination_image->data[x+((destination_image->y)*y)].red   = sample[0]; 

that should be

destination_image->data[x+((destination_image->x)*y)].red   = sample[0]; 

what helps debugging such cases initializing destination image "magic color" that's not present in actual data (e.g. awful pink:-)). notice destination pixels still have color after resize_image() call. hints problem.


Comments

Popular posts from this blog

how to insert data php javascript mysql with multiple array session 2 -

multithreading - Exception in Application constructor -

windows - CertCreateCertificateContext returns CRYPT_E_ASN1_BADTAG / 8009310b -