Advertisement
Guest User

Untitled

a guest
Feb 20th, 2023
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.32 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include "stb_image_write.h"
  5.  
  6. #define STB_IMAGE_WRITE_IMPLEMENTATION
  7. #define CHANNELS 3 // number of color channels
  8. #define BICUBIC_ORDER 4 // bicubic interpolation order
  9. #define BICUBIC_SIZE (BICUBIC_ORDER + 1) // bicubic interpolation kernel size
  10.  
  11. // calculate bicubic kernel weights
  12. void bicubic_weights(float weights[BICUBIC_SIZE], float x)
  13. {
  14. float absx = fabsf(x);
  15. if (absx <= 1.0)
  16. {
  17. weights[0] = (1.5 * absx - 2.5) * absx * absx + 1.0;
  18. weights[1] = (2.0 - 1.5 * absx) * absx * absx;
  19. weights[2] = 0.5 * (absx - 1.0) * absx * absx;
  20. weights[3] = 0.0;
  21. }
  22. else if (absx <= 2.0)
  23. {
  24. weights[0] = -0.5 * absx * absx * absx + 2.5 * absx * absx - 4.0 * absx + 2.0;
  25. weights[1] = 0.5 * absx * absx * absx - 2.5 * absx * absx + 4.0 * absx;
  26. weights[2] = -0.5 * absx * absx * absx + 1.5 * absx * absx;
  27. weights[3] = 0.0;
  28. }
  29. else
  30. {
  31. weights[0] = 0.0;
  32. weights[1] = 0.0;
  33. weights[2] = 0.0;
  34. weights[3] = 0.0;
  35. }
  36. }
  37.  
  38. // perform bicubic interpolation on an image
  39. void bicubic_interpolation(unsigned char *input, int in_w, int in_h, unsigned char *output, int out_w, int out_h)
  40. {
  41. int x, y, c, i, j;
  42. float u, v;
  43. float weights_x[BICUBIC_SIZE], weights_y[BICUBIC_SIZE];
  44. int x_min, y_min, x_max, y_max;
  45. int index, index_offset, offset;
  46. unsigned char pixel[CHANNELS];
  47.  
  48. // calculate scaling factors for x and y axes
  49. float sx = (float)in_w / (float)out_w;
  50. float sy = (float)in_h / (float)out_h;
  51.  
  52. for (y = 0; y < out_h; y++)
  53. {
  54. for (x = 0; x < out_w; x++)
  55. {
  56. // calculate input image coordinates for the current output pixel
  57. u = (float)x * sx;
  58. v = (float)y * sy;
  59.  
  60. // determine the range of input pixel coordinates to use for interpolation
  61. x_min = (int)floorf(u) - BICUBIC_ORDER / 2;
  62. y_min = (int)floorf(v) - BICUBIC_ORDER / 2;
  63. x_max = x_min + BICUBIC_ORDER;
  64. y_max = y_min + BICUBIC_ORDER;
  65.  
  66. // clamp the input pixel coordinate range to the image bounds
  67. if (x_min < 0)
  68. x_min = 0;
  69. if (y_min < 0)
  70. y_min = 0;
  71. if (x_max >= in_w)
  72. x_max = in_w;
  73. if (y_max >= in_h)
  74. y_max = in_h - 1;
  75.  
  76. // initialize output pixel values to zero
  77. for (c = 0; c < CHANNELS; c++)
  78. {
  79. pixel[c] = 0;
  80. }
  81.  
  82. // perform bicubic interpolation for each color channel
  83. for (c = 0; c < CHANNELS; c++)
  84. {
  85. for (j = y_min; j <= y_max; j++)
  86. {
  87. // calculate weights for the y-axis interpolation
  88. bicubic_weights(weights_y, v - (float)j);
  89.  
  90. for (i = x_min; i <= x_max; i++)
  91. {
  92. // calculate weights for the x-axis interpolation
  93. bicubic_weights(weights_x, u - (float)i);
  94.  
  95. // calculate the input pixel index and offset for the current channel
  96. index = (j * in_w + i) * CHANNELS + c;
  97. index_offset = index - (BICUBIC_ORDER / 2) * in_w * CHANNELS - (BICUBIC_ORDER / 2) * CHANNELS;
  98.  
  99. // perform the bicubic interpolation for the current pixel
  100. for (offset = 0; offset < BICUBIC_SIZE; offset++)
  101. {
  102. pixel[c] += input[index_offset + offset * in_w * CHANNELS] * weights_x[offset] * weights_y[BICUBIC_SIZE - 1];
  103. }
  104. }
  105. }
  106. }
  107.  
  108. // copy the output pixel values to the output image
  109. for (c = 0; c < CHANNELS; c++)
  110. {
  111. output[(y * out_w + x) * CHANNELS + c] = (unsigned char)pixel[c];
  112. }
  113. }
  114. }
  115. }
  116.  
  117. // example usage
  118. int main()
  119. {
  120. int in_w = 640;
  121. int in_h = 480;
  122. int out_w = 320;
  123. int out_h = 240;
  124. // allocate memory for the input and output images
  125. unsigned char *input = (unsigned char *)malloc(in_w * in_h * CHANNELS);
  126. unsigned char *output = (unsigned char *)malloc(out_w * out_h * CHANNELS);
  127.  
  128. // populate the input image with data
  129. for (int y = 0; y < in_h; y++)
  130. {
  131. for (int x = 0; x < in_w; x++)
  132. {
  133. for (int c = 0; c < CHANNELS; c++)
  134. {
  135. // calculate the pixel value for the current channel
  136. unsigned char value = (unsigned char)((x + y) / 2);
  137.  
  138. // set the pixel value in the input image
  139. input[(y * in_w + x) * CHANNELS + c] = value;
  140. }
  141. }
  142. }
  143.  
  144. // perform bicubic interpolation on the input image
  145. bicubic_interpolation(input, in_w, in_h, output, out_w, out_h);
  146.  
  147. // write the output image to disk
  148. if (stbi_write_png("output.png", out_w, out_h, CHANNELS, output, out_w * CHANNELS) == 0)
  149. {
  150. fprintf(stderr, "Error writing output image to disk\n");
  151. }
  152.  
  153. // free the allocated memory
  154. free(input);
  155. free(output);
  156.  
  157. return 0;
  158. }
  159.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement