Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

bicubic.c 5.5 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * libpipi Pathetic image processing interface library
  3. * Copyright (c) 2004-2010 Sam Hocevar <sam@hocevar.net>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library is free software. It comes without any warranty, to
  9. * the extent permitted by applicable law. You can redistribute it
  10. * and/or modify it under the terms of the Do What The Fuck You Want
  11. * To Public License, Version 2, as published by Sam Hocevar. See
  12. * http://sam.zoy.org/wtfpl/COPYING for more details.
  13. */
  14. /*
  15. * bicubic.c: Bicubic image resizing functions
  16. */
  17. #include "config.h"
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include "pipi.h"
  21. #include "pipi_internals.h"
  22. static inline int min_int(int a, int b) { return a < b ? a : b; }
  23. static inline int max_int(int a, int b) { return a > b ? a : b; }
  24. pipi_image_t *pipi_resize_bicubic(pipi_image_t *src, int w, int h)
  25. {
  26. float *srcdata, *dstdata, *p0, *p1, *p2, *p3;
  27. pipi_image_t *dst;
  28. pipi_pixels_t *srcp, *dstp;
  29. int x, y, i, sw, dw, sh, dh, i0, i1, i2, i3;
  30. float scalex, scaley;
  31. srcp = pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32);
  32. srcdata = (float *)srcp->pixels;
  33. dst = pipi_new(w, h);
  34. dstp = pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32);
  35. dstdata = (float *)dstp->pixels;
  36. sw = src->w; sh = src->h;
  37. dw = dst->w; dh = dst->h;
  38. scalex = dw > 1 ? (float)(sw - 1) / (dw - 1) : 1.0f;
  39. scaley = dh > 1 ? (float)(sh - 1) / (dh - 1) : 1.0f;
  40. for(y = 0; y < dh; y++)
  41. {
  42. float yfloat = scaley * y;
  43. int yint = (int)yfloat;
  44. float y1 = yfloat - yint;
  45. p0 = srcdata + 4 * sw * min_int(max_int(0, yint - 1), sh - 1);
  46. p1 = srcdata + 4 * sw * min_int(max_int(0, yint ), sh - 1);
  47. p2 = srcdata + 4 * sw * min_int(max_int(0, yint + 1), sh - 1);
  48. p3 = srcdata + 4 * sw * min_int(max_int(0, yint + 2), sh - 1);
  49. for (x = 0; x < dw; x++)
  50. {
  51. float xfloat = scalex * x;
  52. int xint = (int)xfloat;
  53. float x1 = xfloat - xint;
  54. i0 = 4 * min_int(max_int(0, xint - 1), sw - 1);
  55. i1 = 4 * min_int(max_int(0, xint ), sw - 1);
  56. i2 = 4 * min_int(max_int(0, xint + 1), sw - 1);
  57. i3 = 4 * min_int(max_int(0, xint + 2), sw - 1);
  58. for (i = 0; i < 4; i++, i0++, i1++, i2++, i3++)
  59. {
  60. float a00 = p1[i1];
  61. float a01 = .5f * (p2[i1] - p0[i1]);
  62. float a02 = p0[i1] - 2.5f * p1[i1]
  63. + 2.f * p2[i1] - .5f * p3[i1];
  64. float a03 = .5f * (p3[i1] - p0[i1]) + 1.5f * (p1[i1] - p2[i1]);
  65. float a10 = .5f * (p1[i2] - p1[i0]);
  66. float a11 = .25f * (p0[i0] - p2[i0] - p0[i2] + p2[i2]);
  67. float a12 = .5f * (p0[i2] - p0[i0]) + 1.25f * (p1[i0] - p1[i2])
  68. + .25f * (p3[i0] - p3[i2]) + p2[i2] - p2[i0];
  69. float a13 = .25f * (p0[i0] - p3[i0] - p0[i2] + p3[i2])
  70. + .75f * (p2[i0] - p1[i0] + p1[i2] - p2[i2]);
  71. float a20 = p1[i0] - 2.5f * p1[i1]
  72. + 2.f * p1[i2] - .5f * p1[i3];
  73. float a21 = .5f * (p2[i0] - p0[i0]) + 1.25f * (p0[i1] - p2[i1])
  74. + .25f * (p0[i3] - p2[i3]) - p0[i2] + p2[i2];
  75. float a22 = p0[i0] - p3[i2] - 2.5f * (p1[i0] + p0[i1])
  76. + 2.f * (p2[i0] + p0[i2]) - .5f * (p3[i0] + p0[i3])
  77. + 6.25f * p1[i1] - 5.f * (p2[i1] + p1[i2])
  78. + 1.25f * (p3[i1] + p1[i3])
  79. + 4.f * p2[i2] - p2[i3] + .25f * p3[i3];
  80. float a23 = 1.5f * (p1[i0] - p2[i0]) + .5f * (p3[i0] - p0[i0])
  81. + 1.25f * (p0[i1] - p3[i1])
  82. + 3.75f * (p2[i1] - p1[i1]) + p3[i2] - p0[i2]
  83. + 3.f * (p1[i2] - p2[i2]) + .25f * (p0[i3] - p3[i3])
  84. + .75f * (p2[i3] - p1[i3]);
  85. float a30 = .5f * (p1[i3] - p1[i0]) + 1.5f * (p1[i1] - p1[i2]);
  86. float a31 = .25f * (p0[i0] - p2[i0]) + .25f * (p2[i3] - p0[i3])
  87. + .75f * (p2[i1] - p0[i1] + p0[i2] - p2[i2]);
  88. float a32 = -.5f * p0[i0] + 1.25f * p1[i0] - p2[i0]
  89. + .25f * p3[i0] + 1.5f * p0[i1] - 3.75f * p1[i1]
  90. + 3.f * p2[i1] - .75f * p3[i1] - 1.5f * p0[i2]
  91. + 3.75f * p1[i2] - 3.f * p2[i2] + .75f * p3[i2]
  92. + .5f * p0[i3] - 1.25f * p1[i3] + p2[i3]
  93. - .25f * p3[i3];
  94. float a33 = .25f * p0[i0] - .75f * p1[i0] + .75f * p2[i0]
  95. - .25f * p3[i0] - .75f * p0[i1] + 2.25f * p1[i1]
  96. - 2.25f * p2[i1] + .75f * p3[i1] + .75f * p0[i2]
  97. - 2.25f * p1[i2] + 2.25f * p2[i2] - .75f * p3[i2]
  98. - .25f * p0[i3] + .75f * p1[i3] - .75f * p2[i3]
  99. + .25f * p3[i3];
  100. float y2 = y1 * y1; float y3 = y2 * y1;
  101. float x2 = x1 * x1; float x3 = x2 * x1;
  102. float p = a00 + a01 * y1 + a02 * y2 + a03 * y3 +
  103. + a10 * x1 + a11 * x1 * y1 + a12 * x1 * y2 + a13 * x1 * y3
  104. + a20 * x2 + a21 * x2 * y1 + a22 * x2 * y2 + a23 * x2 * y3
  105. + a30 * x3 + a31 * x3 * y1 + a32 * x3 * y2 + a33 * x3 * y3;
  106. if (p < 0.0f) p = 0.0f;
  107. if (p > 1.0f) p = 1.0f;
  108. dstdata[(y * dw + x) * 4 + i] = p;
  109. }
  110. }
  111. }
  112. return dst;
  113. }