Resample.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. #include "Imaging.h"
  2. #include <math.h>
  3. #define ROUND_UP(f) ((int)((f) >= 0.0 ? (f) + 0.5F : (f)-0.5F))
  4. struct filter {
  5. double (*filter)(double x);
  6. double support;
  7. };
  8. static inline double
  9. box_filter(double x) {
  10. if (x > -0.5 && x <= 0.5) {
  11. return 1.0;
  12. }
  13. return 0.0;
  14. }
  15. static inline double
  16. bilinear_filter(double x) {
  17. if (x < 0.0) {
  18. x = -x;
  19. }
  20. if (x < 1.0) {
  21. return 1.0 - x;
  22. }
  23. return 0.0;
  24. }
  25. static inline double
  26. hamming_filter(double x) {
  27. if (x < 0.0) {
  28. x = -x;
  29. }
  30. if (x == 0.0) {
  31. return 1.0;
  32. }
  33. if (x >= 1.0) {
  34. return 0.0;
  35. }
  36. x = x * M_PI;
  37. return sin(x) / x * (0.54f + 0.46f * cos(x));
  38. }
  39. static inline double
  40. bicubic_filter(double x) {
  41. /* https://en.wikipedia.org/wiki/Bicubic_interpolation#Bicubic_convolution_algorithm
  42. */
  43. #define a -0.5
  44. if (x < 0.0) {
  45. x = -x;
  46. }
  47. if (x < 1.0) {
  48. return ((a + 2.0) * x - (a + 3.0)) * x * x + 1;
  49. }
  50. if (x < 2.0) {
  51. return (((x - 5) * x + 8) * x - 4) * a;
  52. }
  53. return 0.0;
  54. #undef a
  55. }
  56. static inline double
  57. sinc_filter(double x) {
  58. if (x == 0.0) {
  59. return 1.0;
  60. }
  61. x = x * M_PI;
  62. return sin(x) / x;
  63. }
  64. static inline double
  65. lanczos_filter(double x) {
  66. /* truncated sinc */
  67. if (-3.0 <= x && x < 3.0) {
  68. return sinc_filter(x) * sinc_filter(x / 3);
  69. }
  70. return 0.0;
  71. }
  72. static struct filter BOX = {box_filter, 0.5};
  73. static struct filter BILINEAR = {bilinear_filter, 1.0};
  74. static struct filter HAMMING = {hamming_filter, 1.0};
  75. static struct filter BICUBIC = {bicubic_filter, 2.0};
  76. static struct filter LANCZOS = {lanczos_filter, 3.0};
  77. /* 8 bits for result. Filter can have negative areas.
  78. In one cases the sum of the coefficients will be negative,
  79. in the other it will be more than 1.0. That is why we need
  80. two extra bits for overflow and int type. */
  81. #define PRECISION_BITS (32 - 8 - 2)
  82. /* Handles values form -640 to 639. */
  83. UINT8 _clip8_lookups[1280] = {
  84. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  85. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  86. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  87. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  88. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  89. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  90. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  91. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  92. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  93. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  94. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  95. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  96. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  97. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  98. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  99. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  100. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  101. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  102. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  103. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  104. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  105. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  106. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  107. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  108. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  109. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  110. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  111. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  112. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  113. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  114. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  115. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  116. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  117. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  118. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  119. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  120. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  121. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
  122. 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
  123. 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  124. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
  125. 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
  126. 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
  127. 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
  128. 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
  129. 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
  130. 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
  131. 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
  132. 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
  133. 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
  134. 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
  135. 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243,
  136. 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 255, 255, 255, 255, 255,
  137. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  138. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  139. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  140. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  141. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  142. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  143. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  144. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  145. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  146. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  147. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  148. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  149. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  150. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  151. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  152. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  153. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  154. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  155. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  156. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  157. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  158. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  159. 255, 255, 255, 255, 255,
  160. };
  161. UINT8 *clip8_lookups = &_clip8_lookups[640];
  162. static inline UINT8
  163. clip8(int in) {
  164. return clip8_lookups[in >> PRECISION_BITS];
  165. }
  166. int
  167. precompute_coeffs(
  168. int inSize,
  169. float in0,
  170. float in1,
  171. int outSize,
  172. struct filter *filterp,
  173. int **boundsp,
  174. double **kkp) {
  175. double support, scale, filterscale;
  176. double center, ww, ss;
  177. int xx, x, ksize, xmin, xmax;
  178. int *bounds;
  179. double *kk, *k;
  180. /* prepare for horizontal stretch */
  181. filterscale = scale = (double)(in1 - in0) / outSize;
  182. if (filterscale < 1.0) {
  183. filterscale = 1.0;
  184. }
  185. /* determine support size (length of resampling filter) */
  186. support = filterp->support * filterscale;
  187. /* maximum number of coeffs */
  188. ksize = (int)ceil(support) * 2 + 1;
  189. // check for overflow
  190. if (outSize > INT_MAX / (ksize * (int)sizeof(double))) {
  191. ImagingError_MemoryError();
  192. return 0;
  193. }
  194. /* coefficient buffer */
  195. /* malloc check ok, overflow checked above */
  196. kk = malloc(outSize * ksize * sizeof(double));
  197. if (!kk) {
  198. ImagingError_MemoryError();
  199. return 0;
  200. }
  201. /* malloc check ok, ksize*sizeof(double) > 2*sizeof(int) */
  202. bounds = malloc(outSize * 2 * sizeof(int));
  203. if (!bounds) {
  204. free(kk);
  205. ImagingError_MemoryError();
  206. return 0;
  207. }
  208. for (xx = 0; xx < outSize; xx++) {
  209. center = in0 + (xx + 0.5) * scale;
  210. ww = 0.0;
  211. ss = 1.0 / filterscale;
  212. // Round the value
  213. xmin = (int)(center - support + 0.5);
  214. if (xmin < 0) {
  215. xmin = 0;
  216. }
  217. // Round the value
  218. xmax = (int)(center + support + 0.5);
  219. if (xmax > inSize) {
  220. xmax = inSize;
  221. }
  222. xmax -= xmin;
  223. k = &kk[xx * ksize];
  224. for (x = 0; x < xmax; x++) {
  225. double w = filterp->filter((x + xmin - center + 0.5) * ss);
  226. k[x] = w;
  227. ww += w;
  228. }
  229. for (x = 0; x < xmax; x++) {
  230. if (ww != 0.0) {
  231. k[x] /= ww;
  232. }
  233. }
  234. // Remaining values should stay empty if they are used despite of xmax.
  235. for (; x < ksize; x++) {
  236. k[x] = 0;
  237. }
  238. bounds[xx * 2 + 0] = xmin;
  239. bounds[xx * 2 + 1] = xmax;
  240. }
  241. *boundsp = bounds;
  242. *kkp = kk;
  243. return ksize;
  244. }
  245. void
  246. normalize_coeffs_8bpc(int outSize, int ksize, double *prekk) {
  247. int x;
  248. INT32 *kk;
  249. // use the same buffer for normalized coefficients
  250. kk = (INT32 *)prekk;
  251. for (x = 0; x < outSize * ksize; x++) {
  252. if (prekk[x] < 0) {
  253. kk[x] = (int)(-0.5 + prekk[x] * (1 << PRECISION_BITS));
  254. } else {
  255. kk[x] = (int)(0.5 + prekk[x] * (1 << PRECISION_BITS));
  256. }
  257. }
  258. }
  259. void
  260. ImagingResampleHorizontal_8bpc(
  261. Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *prekk) {
  262. ImagingSectionCookie cookie;
  263. int ss0, ss1, ss2, ss3;
  264. int xx, yy, x, xmin, xmax;
  265. INT32 *k, *kk;
  266. // use the same buffer for normalized coefficients
  267. kk = (INT32 *)prekk;
  268. normalize_coeffs_8bpc(imOut->xsize, ksize, prekk);
  269. ImagingSectionEnter(&cookie);
  270. if (imIn->image8) {
  271. for (yy = 0; yy < imOut->ysize; yy++) {
  272. for (xx = 0; xx < imOut->xsize; xx++) {
  273. xmin = bounds[xx * 2 + 0];
  274. xmax = bounds[xx * 2 + 1];
  275. k = &kk[xx * ksize];
  276. ss0 = 1 << (PRECISION_BITS - 1);
  277. for (x = 0; x < xmax; x++) {
  278. ss0 += ((UINT8)imIn->image8[yy + offset][x + xmin]) * k[x];
  279. }
  280. imOut->image8[yy][xx] = clip8(ss0);
  281. }
  282. }
  283. } else if (imIn->type == IMAGING_TYPE_UINT8) {
  284. if (imIn->bands == 2) {
  285. for (yy = 0; yy < imOut->ysize; yy++) {
  286. for (xx = 0; xx < imOut->xsize; xx++) {
  287. UINT32 v;
  288. xmin = bounds[xx * 2 + 0];
  289. xmax = bounds[xx * 2 + 1];
  290. k = &kk[xx * ksize];
  291. ss0 = ss3 = 1 << (PRECISION_BITS - 1);
  292. for (x = 0; x < xmax; x++) {
  293. ss0 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 0]) *
  294. k[x];
  295. ss3 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 3]) *
  296. k[x];
  297. }
  298. v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3));
  299. memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
  300. }
  301. }
  302. } else if (imIn->bands == 3) {
  303. for (yy = 0; yy < imOut->ysize; yy++) {
  304. for (xx = 0; xx < imOut->xsize; xx++) {
  305. UINT32 v;
  306. xmin = bounds[xx * 2 + 0];
  307. xmax = bounds[xx * 2 + 1];
  308. k = &kk[xx * ksize];
  309. ss0 = ss1 = ss2 = 1 << (PRECISION_BITS - 1);
  310. for (x = 0; x < xmax; x++) {
  311. ss0 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 0]) *
  312. k[x];
  313. ss1 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 1]) *
  314. k[x];
  315. ss2 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 2]) *
  316. k[x];
  317. }
  318. v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0);
  319. memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
  320. }
  321. }
  322. } else {
  323. for (yy = 0; yy < imOut->ysize; yy++) {
  324. for (xx = 0; xx < imOut->xsize; xx++) {
  325. UINT32 v;
  326. xmin = bounds[xx * 2 + 0];
  327. xmax = bounds[xx * 2 + 1];
  328. k = &kk[xx * ksize];
  329. ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS - 1);
  330. for (x = 0; x < xmax; x++) {
  331. ss0 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 0]) *
  332. k[x];
  333. ss1 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 1]) *
  334. k[x];
  335. ss2 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 2]) *
  336. k[x];
  337. ss3 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 3]) *
  338. k[x];
  339. }
  340. v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3));
  341. memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
  342. }
  343. }
  344. }
  345. }
  346. ImagingSectionLeave(&cookie);
  347. }
  348. void
  349. ImagingResampleVertical_8bpc(
  350. Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *prekk) {
  351. ImagingSectionCookie cookie;
  352. int ss0, ss1, ss2, ss3;
  353. int xx, yy, y, ymin, ymax;
  354. INT32 *k, *kk;
  355. // use the same buffer for normalized coefficients
  356. kk = (INT32 *)prekk;
  357. normalize_coeffs_8bpc(imOut->ysize, ksize, prekk);
  358. ImagingSectionEnter(&cookie);
  359. if (imIn->image8) {
  360. for (yy = 0; yy < imOut->ysize; yy++) {
  361. k = &kk[yy * ksize];
  362. ymin = bounds[yy * 2 + 0];
  363. ymax = bounds[yy * 2 + 1];
  364. for (xx = 0; xx < imOut->xsize; xx++) {
  365. ss0 = 1 << (PRECISION_BITS - 1);
  366. for (y = 0; y < ymax; y++) {
  367. ss0 += ((UINT8)imIn->image8[y + ymin][xx]) * k[y];
  368. }
  369. imOut->image8[yy][xx] = clip8(ss0);
  370. }
  371. }
  372. } else if (imIn->type == IMAGING_TYPE_UINT8) {
  373. if (imIn->bands == 2) {
  374. for (yy = 0; yy < imOut->ysize; yy++) {
  375. k = &kk[yy * ksize];
  376. ymin = bounds[yy * 2 + 0];
  377. ymax = bounds[yy * 2 + 1];
  378. for (xx = 0; xx < imOut->xsize; xx++) {
  379. UINT32 v;
  380. ss0 = ss3 = 1 << (PRECISION_BITS - 1);
  381. for (y = 0; y < ymax; y++) {
  382. ss0 += ((UINT8)imIn->image[y + ymin][xx * 4 + 0]) * k[y];
  383. ss3 += ((UINT8)imIn->image[y + ymin][xx * 4 + 3]) * k[y];
  384. }
  385. v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3));
  386. memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
  387. }
  388. }
  389. } else if (imIn->bands == 3) {
  390. for (yy = 0; yy < imOut->ysize; yy++) {
  391. k = &kk[yy * ksize];
  392. ymin = bounds[yy * 2 + 0];
  393. ymax = bounds[yy * 2 + 1];
  394. for (xx = 0; xx < imOut->xsize; xx++) {
  395. UINT32 v;
  396. ss0 = ss1 = ss2 = 1 << (PRECISION_BITS - 1);
  397. for (y = 0; y < ymax; y++) {
  398. ss0 += ((UINT8)imIn->image[y + ymin][xx * 4 + 0]) * k[y];
  399. ss1 += ((UINT8)imIn->image[y + ymin][xx * 4 + 1]) * k[y];
  400. ss2 += ((UINT8)imIn->image[y + ymin][xx * 4 + 2]) * k[y];
  401. }
  402. v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0);
  403. memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
  404. }
  405. }
  406. } else {
  407. for (yy = 0; yy < imOut->ysize; yy++) {
  408. k = &kk[yy * ksize];
  409. ymin = bounds[yy * 2 + 0];
  410. ymax = bounds[yy * 2 + 1];
  411. for (xx = 0; xx < imOut->xsize; xx++) {
  412. UINT32 v;
  413. ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS - 1);
  414. for (y = 0; y < ymax; y++) {
  415. ss0 += ((UINT8)imIn->image[y + ymin][xx * 4 + 0]) * k[y];
  416. ss1 += ((UINT8)imIn->image[y + ymin][xx * 4 + 1]) * k[y];
  417. ss2 += ((UINT8)imIn->image[y + ymin][xx * 4 + 2]) * k[y];
  418. ss3 += ((UINT8)imIn->image[y + ymin][xx * 4 + 3]) * k[y];
  419. }
  420. v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3));
  421. memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
  422. }
  423. }
  424. }
  425. }
  426. ImagingSectionLeave(&cookie);
  427. }
  428. void
  429. ImagingResampleHorizontal_32bpc(
  430. Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk) {
  431. ImagingSectionCookie cookie;
  432. double ss;
  433. int xx, yy, x, xmin, xmax;
  434. double *k;
  435. ImagingSectionEnter(&cookie);
  436. switch (imIn->type) {
  437. case IMAGING_TYPE_INT32:
  438. for (yy = 0; yy < imOut->ysize; yy++) {
  439. for (xx = 0; xx < imOut->xsize; xx++) {
  440. xmin = bounds[xx * 2 + 0];
  441. xmax = bounds[xx * 2 + 1];
  442. k = &kk[xx * ksize];
  443. ss = 0.0;
  444. for (x = 0; x < xmax; x++) {
  445. ss += IMAGING_PIXEL_I(imIn, x + xmin, yy + offset) * k[x];
  446. }
  447. IMAGING_PIXEL_I(imOut, xx, yy) = ROUND_UP(ss);
  448. }
  449. }
  450. break;
  451. case IMAGING_TYPE_FLOAT32:
  452. for (yy = 0; yy < imOut->ysize; yy++) {
  453. for (xx = 0; xx < imOut->xsize; xx++) {
  454. xmin = bounds[xx * 2 + 0];
  455. xmax = bounds[xx * 2 + 1];
  456. k = &kk[xx * ksize];
  457. ss = 0.0;
  458. for (x = 0; x < xmax; x++) {
  459. ss += IMAGING_PIXEL_F(imIn, x + xmin, yy + offset) * k[x];
  460. }
  461. IMAGING_PIXEL_F(imOut, xx, yy) = ss;
  462. }
  463. }
  464. break;
  465. }
  466. ImagingSectionLeave(&cookie);
  467. }
  468. void
  469. ImagingResampleVertical_32bpc(
  470. Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk) {
  471. ImagingSectionCookie cookie;
  472. double ss;
  473. int xx, yy, y, ymin, ymax;
  474. double *k;
  475. ImagingSectionEnter(&cookie);
  476. switch (imIn->type) {
  477. case IMAGING_TYPE_INT32:
  478. for (yy = 0; yy < imOut->ysize; yy++) {
  479. ymin = bounds[yy * 2 + 0];
  480. ymax = bounds[yy * 2 + 1];
  481. k = &kk[yy * ksize];
  482. for (xx = 0; xx < imOut->xsize; xx++) {
  483. ss = 0.0;
  484. for (y = 0; y < ymax; y++) {
  485. ss += IMAGING_PIXEL_I(imIn, xx, y + ymin) * k[y];
  486. }
  487. IMAGING_PIXEL_I(imOut, xx, yy) = ROUND_UP(ss);
  488. }
  489. }
  490. break;
  491. case IMAGING_TYPE_FLOAT32:
  492. for (yy = 0; yy < imOut->ysize; yy++) {
  493. ymin = bounds[yy * 2 + 0];
  494. ymax = bounds[yy * 2 + 1];
  495. k = &kk[yy * ksize];
  496. for (xx = 0; xx < imOut->xsize; xx++) {
  497. ss = 0.0;
  498. for (y = 0; y < ymax; y++) {
  499. ss += IMAGING_PIXEL_F(imIn, xx, y + ymin) * k[y];
  500. }
  501. IMAGING_PIXEL_F(imOut, xx, yy) = ss;
  502. }
  503. }
  504. break;
  505. }
  506. ImagingSectionLeave(&cookie);
  507. }
  508. typedef void (*ResampleFunction)(
  509. Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk);
  510. Imaging
  511. ImagingResampleInner(
  512. Imaging imIn,
  513. int xsize,
  514. int ysize,
  515. struct filter *filterp,
  516. float box[4],
  517. ResampleFunction ResampleHorizontal,
  518. ResampleFunction ResampleVertical);
  519. Imaging
  520. ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) {
  521. struct filter *filterp;
  522. ResampleFunction ResampleHorizontal;
  523. ResampleFunction ResampleVertical;
  524. if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "1") == 0) {
  525. return (Imaging)ImagingError_ModeError();
  526. }
  527. if (imIn->type == IMAGING_TYPE_SPECIAL) {
  528. return (Imaging)ImagingError_ModeError();
  529. } else if (imIn->image8) {
  530. ResampleHorizontal = ImagingResampleHorizontal_8bpc;
  531. ResampleVertical = ImagingResampleVertical_8bpc;
  532. } else {
  533. switch (imIn->type) {
  534. case IMAGING_TYPE_UINT8:
  535. ResampleHorizontal = ImagingResampleHorizontal_8bpc;
  536. ResampleVertical = ImagingResampleVertical_8bpc;
  537. break;
  538. case IMAGING_TYPE_INT32:
  539. case IMAGING_TYPE_FLOAT32:
  540. ResampleHorizontal = ImagingResampleHorizontal_32bpc;
  541. ResampleVertical = ImagingResampleVertical_32bpc;
  542. break;
  543. default:
  544. return (Imaging)ImagingError_ModeError();
  545. }
  546. }
  547. /* check filter */
  548. switch (filter) {
  549. case IMAGING_TRANSFORM_BOX:
  550. filterp = &BOX;
  551. break;
  552. case IMAGING_TRANSFORM_BILINEAR:
  553. filterp = &BILINEAR;
  554. break;
  555. case IMAGING_TRANSFORM_HAMMING:
  556. filterp = &HAMMING;
  557. break;
  558. case IMAGING_TRANSFORM_BICUBIC:
  559. filterp = &BICUBIC;
  560. break;
  561. case IMAGING_TRANSFORM_LANCZOS:
  562. filterp = &LANCZOS;
  563. break;
  564. default:
  565. return (Imaging)ImagingError_ValueError("unsupported resampling filter");
  566. }
  567. return ImagingResampleInner(
  568. imIn, xsize, ysize, filterp, box, ResampleHorizontal, ResampleVertical);
  569. }
  570. Imaging
  571. ImagingResampleInner(
  572. Imaging imIn,
  573. int xsize,
  574. int ysize,
  575. struct filter *filterp,
  576. float box[4],
  577. ResampleFunction ResampleHorizontal,
  578. ResampleFunction ResampleVertical) {
  579. Imaging imTemp = NULL;
  580. Imaging imOut = NULL;
  581. int i, need_horizontal, need_vertical;
  582. int ybox_first, ybox_last;
  583. int ksize_horiz, ksize_vert;
  584. int *bounds_horiz, *bounds_vert;
  585. double *kk_horiz, *kk_vert;
  586. need_horizontal = xsize != imIn->xsize || box[0] || box[2] != xsize;
  587. need_vertical = ysize != imIn->ysize || box[1] || box[3] != ysize;
  588. ksize_horiz = precompute_coeffs(
  589. imIn->xsize, box[0], box[2], xsize, filterp, &bounds_horiz, &kk_horiz);
  590. if (!ksize_horiz) {
  591. return NULL;
  592. }
  593. ksize_vert = precompute_coeffs(
  594. imIn->ysize, box[1], box[3], ysize, filterp, &bounds_vert, &kk_vert);
  595. if (!ksize_vert) {
  596. free(bounds_horiz);
  597. free(kk_horiz);
  598. return NULL;
  599. }
  600. // First used row in the source image
  601. ybox_first = bounds_vert[0];
  602. // Last used row in the source image
  603. ybox_last = bounds_vert[ysize * 2 - 2] + bounds_vert[ysize * 2 - 1];
  604. /* two-pass resize, horizontal pass */
  605. if (need_horizontal) {
  606. // Shift bounds for vertical pass
  607. for (i = 0; i < ysize; i++) {
  608. bounds_vert[i * 2] -= ybox_first;
  609. }
  610. imTemp = ImagingNewDirty(imIn->mode, xsize, ybox_last - ybox_first);
  611. if (imTemp) {
  612. ResampleHorizontal(
  613. imTemp, imIn, ybox_first, ksize_horiz, bounds_horiz, kk_horiz);
  614. }
  615. free(bounds_horiz);
  616. free(kk_horiz);
  617. if (!imTemp) {
  618. free(bounds_vert);
  619. free(kk_vert);
  620. return NULL;
  621. }
  622. imOut = imIn = imTemp;
  623. } else {
  624. // Free in any case
  625. free(bounds_horiz);
  626. free(kk_horiz);
  627. }
  628. /* vertical pass */
  629. if (need_vertical) {
  630. imOut = ImagingNewDirty(imIn->mode, imIn->xsize, ysize);
  631. if (imOut) {
  632. /* imIn can be the original image or horizontally resampled one */
  633. ResampleVertical(imOut, imIn, 0, ksize_vert, bounds_vert, kk_vert);
  634. }
  635. /* it's safe to call ImagingDelete with empty value
  636. if previous step was not performed. */
  637. ImagingDelete(imTemp);
  638. free(bounds_vert);
  639. free(kk_vert);
  640. if (!imOut) {
  641. return NULL;
  642. }
  643. } else {
  644. // Free in any case
  645. free(bounds_vert);
  646. free(kk_vert);
  647. }
  648. /* none of the previous steps are performed, copying */
  649. if (!imOut) {
  650. imOut = ImagingCopy(imIn);
  651. }
  652. return imOut;
  653. }