comparison Fotopoulos-dir/common.c @ 24:9f20bce6184e v0.7

move directories, support netpbm 11
author Peter Meerwald-Stadler <pmeerw@pmeerw.net>
date Fri, 20 Dec 2024 13:08:59 +0100
parents Fotopoulos/common.c@cbecc570129d
children
comparison
equal deleted inserted replaced
23:71dd4b96221b 24:9f20bce6184e
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include <float.h>
6 #include "netpbm/pgm.h"
7 #include "common.h"
8
9 #define IA 16807
10 #define IM 2147483647
11 #define AM (1.0/IM)
12 #define IQ 127773
13 #define IR 2836
14 #define MASK 123459876
15
16 static int NN = 0;
17 static int m = 0;
18 static double two_over_N = 0;
19 static double root2_over_rootN = 0;
20 static double *C = NULL;
21
22 static gray maxval;
23 static int format;
24
25 void open_image(FILE *in, int *width, int *height)
26 {
27
28 pgm_readpgminit(in, width, height, &maxval, &format);
29 }
30
31 void load_image(int **im, FILE *in, int width, int height)
32 {
33 int col, row;
34 gray *rowbuf;
35
36 rowbuf = malloc(sizeof(gray) * width);
37
38 for (row = 0; row < height; row++) {
39 pgm_readpgmrow(in, rowbuf, width, maxval, format);
40 for (col = 0; col < width; col++)
41 im[row][col] = rowbuf[col];
42 }
43
44 free(rowbuf);
45 }
46
47 void save_image(int **im, FILE *out, int width, int height)
48 {
49 int col, row;
50 gray *rowbuf;
51
52 pgm_writepgminit(out, width, height, 255, 0);
53
54 rowbuf = malloc(sizeof(gray) * width);
55
56 for (row = 0; row < height; row++) {
57 for (col = 0; col < width; col++)
58 rowbuf[col] = im[row][col];
59 pgm_writepgmrow(out, rowbuf, width, 255, 0);
60 }
61
62 free(rowbuf);
63 }
64
65 int ** imatrix(int nrows, int ncols)
66 {
67 int **m;
68 int i, j;
69 m = (int **) malloc (nrows * sizeof(int *));
70 for (i = 0; i < nrows; i++) {
71 m[i] = (int *) malloc (ncols * sizeof(int));
72 if (!m[i]) fprintf(stderr, "\nIt's not working");
73 }
74 for (i = 0; i < nrows; i++)
75 for (j = 0; j < ncols; j++)
76 m[i][j] = 0;
77 return m;
78 }
79
80 void freematrix(int **I, int rows)
81 {
82 int k;
83 for (k = 0; k < rows; k++)
84 free (I[k]);
85 }
86
87 float ran0(long int *idum)
88 {
89 long int k;
90 float ans;
91 *idum ^= MASK;
92 k = (*idum) / IQ;
93 *idum = IA * (*idum - k * IQ) - IR * k;
94 if (*idum < 0) *idum += IM;
95 ans = AM * (*idum);
96 *idum ^= MASK;
97 return ans;
98 }
99
100 float gasdev(long int *idum)
101 {
102
103 float v1;
104 v1 = (float) sqrt( -2.0 * log(ran0(idum))) * cos(2 * PI * ran0(idum));
105 return v1;
106 }
107
108
109 void put_image_from_int_2_double(int **i, double *f, int N)
110 {
111 int l, j, k;
112 k = 0;
113 for (l = 0; l < N; l++)
114 for (j = 0; j < N; j++)
115 f[k++] = (double) i[l][j];
116 }
117
118 void put_image_from_double_2_int(double *f, int **i, int N)
119 {
120 int l, j, k;
121 k = 0;
122 for (l = 0; l < N; l++)
123 for (j = 0; j < N; j++)
124 i[l][j] = (int) f[k++];
125 }
126
127
128 void bitrev(double *f, int len)
129 {
130 int i, j, m, halflen;
131 double temp;
132
133 if (len <= 2) return ; /* No action necessary if n=1 or n=2 */
134 halflen = len >> 1;
135 j = 1;
136 for (i = 1; i <= len; i++) {
137 if (i < j) {
138 temp = f[j - 1];
139 f[j - 1] = f[i - 1];
140 f[i - 1] = temp;
141 }
142 m = halflen;
143 while (j > m) {
144 j = j - m;
145 m = (m + 1) >> 1;
146 }
147 j = j + m;
148 }
149 }
150
151 void inv_sums(double *f)
152 {
153 int stepsize, stage, curptr, nthreads, thread, step, nsteps;
154
155 for (stage = 1; stage <= m - 1; stage++) {
156 nthreads = 1 << (stage - 1);
157 stepsize = nthreads << 1;
158 nsteps = (1 << (m - stage)) - 1;
159 for (thread = 1; thread <= nthreads; thread++) {
160 curptr = NN - thread;
161 for (step = 1; step <= nsteps; step++) {
162 f[curptr] += f[curptr - stepsize];
163 curptr -= stepsize;
164 }
165 }
166 }
167 }
168
169 //--------------------------------------------------------
170 //Foreign code - FCT from Bath Univerity
171 //--------------------------------------------------------
172 void rarrwrt(double f[], int n)
173 {
174 int i;
175
176 for (i = 0; i <= n - 1; i++) {
177 fprintf(stderr, "%4d : %f\n", i, f[i]);
178 }
179 }
180
181 /* fast DCT based on IEEE signal proc, 1992 #8, yugoslavian authors. */
182
183 void fwd_sums(double *f)
184 {
185 int stepsize, stage, curptr, nthreads, thread, step, nsteps;
186
187 for (stage = m - 1; stage >= 1; stage--) {
188 nthreads = 1 << (stage - 1);
189 stepsize = nthreads << 1;
190 nsteps = (1 << (m - stage)) - 1;
191 for (thread = 1; thread <= nthreads; thread++) {
192 curptr = nthreads + thread - 1;
193 for (step = 1; step <= nsteps; step++) {
194 f[curptr] += f[curptr + stepsize];
195 curptr += stepsize;
196 }
197 }
198 }
199 }
200
201 void scramble(double *f, int len)
202 {
203 double temp;
204 int i, ii1, ii2, halflen, qtrlen;
205
206 halflen = len >> 1;
207 qtrlen = halflen >> 1;
208 bitrev(f, len);
209 bitrev(&f[0], halflen);
210 bitrev(&f[halflen], halflen);
211 ii1 = len - 1;
212 ii2 = halflen;
213 for (i = 0; i <= qtrlen - 1; i++) {
214 temp = f[ii1];
215 f[ii1] = f[ii2];
216 f[ii2] = temp;
217 ii1--;
218 ii2++;
219 }
220 }
221
222 void unscramble(double *f, int len)
223 {
224 double temp;
225 int i, ii1, ii2, halflen, qtrlen;
226
227 halflen = len >> 1;
228 qtrlen = halflen >> 1;
229 ii1 = len - 1;
230 ii2 = halflen;
231 for (i = 0; i <= qtrlen - 1; i++) {
232 temp = f[ii1];
233 f[ii1] = f[ii2];
234 f[ii2] = temp;
235 ii1--;
236 ii2++;
237 }
238 bitrev(&f[0], halflen);
239 bitrev(&f[halflen], halflen);
240 bitrev(f, len);
241 }
242
243 void initcosarray(int length)
244 {
245 int i, group, base, item, nitems, halfN;
246 double factor;
247
248 m = -1;
249 do {
250 m++;
251 NN = 1 << m;
252 if (NN > length) {
253 fprintf(stderr, "ERROR in FCT-- length %d not a power of 2\n", length);
254 exit(1);
255 }
256 } while (NN < length);
257 if (C != NULL) free(C);
258 C = (double *)calloc(NN, sizeof(double));
259 if (C == NULL) {
260 fprintf(stderr, "Unable to allocate C array\n");
261 exit(1);
262 }
263 halfN = NN / 2;
264 two_over_N = 2.0 / (double)NN;
265 root2_over_rootN = sqrt(2.0 / (double)NN);
266 for (i = 0; i <= halfN - 1; i++) C[halfN + i] = 4 * i + 1;
267 for (group = 1; group <= m - 1; group++) {
268 base = 1 << (group - 1);
269 nitems = base;
270 factor = 1.0 * (1 << (m - group));
271 for (item = 1; item <= nitems; item++) C[base + item - 1] = factor * C[halfN + item - 1];
272 }
273
274 //printf("before taking cos, C array =\n"); rarrwrt(C,N);
275 for (i = 1; i <= NN - 1; i++) C[i] = 1.0 / (2.0 * cos(C[i] * PI / (2.0 * NN)));
276 //printf("After taking cos, Carray = \n"); rarrwrt(C,N);
277 }
278
279
280 void inv_butterflies(double *f)
281 {
282 int stage, ii1, ii2, butterfly, ngroups, group, wingspan, increment, baseptr;
283 double Cfac, T;
284
285 for (stage = 1; stage <= m; stage++) {
286 ngroups = 1 << (m - stage);
287 wingspan = 1 << (stage - 1);
288 increment = wingspan << 1;
289 for (butterfly = 1; butterfly <= wingspan; butterfly++) {
290 Cfac = C[wingspan + butterfly - 1];
291 baseptr = 0;
292 for (group = 1; group <= ngroups; group++) {
293 ii1 = baseptr + butterfly - 1;
294 ii2 = ii1 + wingspan;
295 T = Cfac * f[ii2];
296 f[ii2] = f[ii1]-T;
297 f[ii1] = f[ii1] + T;
298 baseptr += increment;
299 }
300 }
301 }
302 }
303
304 void fwd_butterflies(double *f)
305 {
306 int stage, ii1, ii2, butterfly, ngroups, group, wingspan, increment, baseptr;
307 double Cfac, T;
308
309 for (stage = m; stage >= 1; stage--) {
310 ngroups = 1 << (m - stage);
311 wingspan = 1 << (stage - 1);
312 increment = wingspan << 1;
313 for (butterfly = 1; butterfly <= wingspan; butterfly++) {
314 Cfac = C[wingspan + butterfly - 1];
315 baseptr = 0;
316 for (group = 1; group <= ngroups; group++) {
317 ii1 = baseptr + butterfly - 1;
318 ii2 = ii1 + wingspan;
319 T = f[ii2];
320 f[ii2] = Cfac * (f[ii1]-T);
321 f[ii1] = f[ii1] + T;
322 baseptr += increment;
323 }
324 }
325 }
326 }
327
328 void ifct_noscale(double *f, int length)
329 {
330 if (length != NN) initcosarray(length);
331 f[0] *= INVROOT2;
332 inv_sums(f);
333 bitrev(f, NN);
334 inv_butterflies(f);
335 unscramble(f, NN);
336 }
337
338 void fct_noscale(double *f, int length)
339 {
340 if (length != NN) initcosarray(length);
341 scramble(f, NN);
342 fwd_butterflies(f);
343 bitrev(f, NN);
344 fwd_sums(f);
345 f[0] *= INVROOT2;
346 }
347
348 void ifct_defn_scaling(double *f, int length)
349 {
350 ifct_noscale(f, length);
351 }
352
353 void fct_defn_scaling(double *f, int length)
354 {
355 int i;
356
357 fct_noscale(f, length);
358 for (i = 0; i <= NN - 1; i++) f[i] *= two_over_N;
359 }
360
361 void ifct(double *f, int length)
362 {
363 /* CALL THIS FOR INVERSE 1D DCT DON-MONRO PREFERRED SCALING */
364 int i;
365
366 if (length != NN) initcosarray(length); /* BGS patch June 1997 */
367 for (i = 0; i <= NN - 1; i++) f[i] *= root2_over_rootN;
368 ifct_noscale(f, length);
369 }
370
371 void fct(double *f, int length)
372 {
373 /* CALL THIS FOR FORWARD 1D DCT DON-MONRO PREFERRED SCALING */
374 int i;
375
376 fct_noscale(f, length);
377 for (i = 0; i <= NN - 1; i++) f[i] *= root2_over_rootN;
378 }
379
380 /****************************************************************
381 2D FAST DCT SECTION
382 ****************************************************************/
383
384 static double *g = NULL;
385 static double two_over_sqrtncolsnrows = 0.0;
386 static int ncolsvalue = 0;
387 static int nrowsvalue = 0;
388
389 void initfct2d(int nrows, int ncols)
390 {
391 if ((nrows <= 0) || (ncols < 0)) {
392 fprintf(stderr, "FCT2D -- ncols=%d or nrows=%d is <=0\n", nrows, ncols);
393 exit(1);
394 }
395 if (g != NULL) free(g);
396 g = (double *)calloc(nrows, sizeof(double));
397 if (g == NULL) {
398 fprintf(stderr, "FCT2D -- Unable to allocate g array\n");
399 exit(1);
400 }
401 ncolsvalue = ncols;
402 nrowsvalue = nrows;
403 two_over_sqrtncolsnrows = 2.0 / sqrt(ncols * 1.0 * nrows);
404 }
405
406 void fct2d(double f[], int nrows, int ncols)
407 /* CALL THIS FOR FORWARD 2d DCT DON-MONRO PREFERRED SCALING */
408 {
409 int u, v;
410
411 if ((ncols != ncolsvalue) || (nrows != nrowsvalue)){
412 initfct2d(nrows, ncols);
413 }
414 for (u = 0; u <= nrows - 1; u++){
415 fct_noscale(&f[u*ncols], ncols);
416 }
417 for (v = 0; v <= ncols - 1; v++){
418 for (u = 0; u <= nrows - 1; u++) {
419 g[u] = f[u * ncols + v];
420 }
421 fct_noscale(g, nrows);
422 for (u = 0; u <= nrows - 1; u++) {
423 f[u*ncols + v] = g[u] * two_over_sqrtncolsnrows;
424 }
425 }
426 }
427
428 void ifct2d(double f[], int nrows, int ncols)
429 /* CALL THIS FOR INVERSE 2d DCT DON-MONRO PREFERRED SCALING */
430 {
431 int u, v;
432
433 if ((ncols != ncolsvalue) || (nrows != nrowsvalue)){
434 initfct2d(nrows, ncols);
435 }
436 for (u = 0; u <= nrows - 1; u++){
437 ifct_noscale(&f[u*ncols], ncols);
438 }
439 for (v = 0; v <= ncols - 1; v++){
440 for (u = 0; u <= nrows - 1; u++) {
441 g[u] = f[u * ncols + v];
442 }
443 ifct_noscale(g, nrows);
444 for (u = 0; u <= nrows - 1; u++) {
445 f[u*ncols + v] = g[u] * two_over_sqrtncolsnrows;
446 }
447 }
448 }
449
450 void matmul(double **a, double **b, double **r, int N)
451 {
452 int i, j, k;
453
454 for (i = 0; i < N; i++)
455 for (j = 0; j < N; j++) {
456 r[i][j] = 0.0;
457 for (k = 0; k < N; k++)
458 r[i][j] += a[i][k] * b[k][j];
459 }
460 }
461
462 void hartley(double **in, double **out, int N)
463 {
464 int k, n;
465 double **h;
466
467 h = dmatrix(N, N);
468 //Building up the transformation matrix
469 for (k = 0; k < N; k++)
470 for (n = 0; n < N; n++)
471 h[k][n] = (cos(2 * PI * k * n / N) + sin(2 * PI * k * n / N)) / sqrt(N);
472
473 // Now we have to multiply the input with the transformation matrix
474 matmul(h, in, out, N);
475 freematrix_d(h, N);
476 return ;
477 }
478
479 double ** dmatrix(int nrows, int ncols)
480 {
481 double **m;
482 int i, j;
483 m = (double **) malloc (nrows * sizeof(double *));
484 for (i = 0; i < nrows; i++) {
485 m[i] = (double *) malloc (ncols * sizeof(double));
486 if (!m[i]) printf("\nIt's not working");
487 }
488 for (i = 0; i < nrows; i++)
489 for (j = 0; j < ncols; j++)
490 m[i][j] = 0.0;
491 return m;
492 }
493
494 void freematrix_d(double **I, int rows)
495 {
496 int k;
497 for (k = 0; k < rows; k++)
498 free (I[k]);
499 }
500
501 void matrix_i2d(int **i, double **d, int N)
502 {
503 int x, y;
504 for (x = 0; x < N; x++)
505 for (y = 0; y < N; y++)
506 d[y][x] = i[y][x];
507 }
508
509 void matrix_d2i(double **d, int **i, int N)
510 {
511 int x, y;
512 for (x = 0; x < N; x++)
513 for (y = 0; y < N; y++)
514 i[y][x] = d[y][x];
515 }
516
517 double * dvector(long int N)
518 {
519 double *m;
520 m = (double *) malloc (N * sizeof(double));
521 if (!m) printf("\nIt's not working");
522 return m;
523 }
524
525 void put_matrix_2_vector(double **i, double *f, int N)
526 {
527 int l, j, k;
528 k = 0;
529 for (l = 0; l < N; l++)
530 for (j = 0; j < N; j++)
531 f[k++] = i[l][j];
532 }
533
534 void put_vector_2_matrix(double *f, double **i, int N)
535 {
536 int l, j, k;
537 k = 0;
538 for (l = 0; l < N; l++)
539 for (j = 0; j < N; j++)
540 i[l][j] = f[k++];
541 }
542
543 void set_in_binary() {
544 #if defined(EMX)
545 _fsetmode(in, "b");
546 #elif defined(MINGW)
547 setmode(STDIN_FILENO, O_BINARY);
548 #endif
549 }
550
551 void set_out_binary() {
552 #if defined(EMX)
553 _fsetmode(out, "b");
554 #elif defined(MINGW)
555 setmode(STDOUT_FILENO, O_BINARY);
556 #endif
557 }
558
559 void wm_init2() {
560 set_out_binary();
561 }
562
563 void wm_init1() {
564 set_in_binary();
565 }
566
567 void wm_init() {
568 set_in_binary();
569 set_out_binary();
570 }
571

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.