]>
Commit | Line | Data |
---|---|---|
3d481f66 PG |
1 | /* |
2 | fujiturn.c by Dave Coffin | |
3 | ||
4 | UNIX filter to correct the 45-degree rotation in images from | |
5 | Fuji digital cameras. Compile with -D_16BIT to rotate 48-bit | |
6 | PPM images. Sample usage: | |
7 | ||
8 | dcraw -c -j dscf0000.raf | fujiturn | pnmscale 0.70710678 > dscf0000.ppm | |
9 | ||
10 | $Revision$ | |
11 | $Date$ | |
12 | ||
13 | */ | |
14 | ||
15 | #include <stdio.h> | |
16 | #include <stdlib.h> | |
17 | #include <fcntl.h> | |
18 | ||
19 | #ifdef _16BIT | |
20 | typedef unsigned short value; | |
21 | #else | |
22 | typedef unsigned char value; | |
23 | #define ntohs(x) (x) | |
24 | #define htons(x) (x) | |
25 | #endif | |
26 | ||
27 | void merror (void *ptr, char *what) | |
28 | { | |
29 | if (ptr) return; | |
30 | fprintf (stderr, "Not enough memory for %s\n", what); | |
31 | exit(1); | |
32 | } | |
33 | ||
34 | int main() | |
35 | { | |
36 | FILE *ifp, *ofp; | |
37 | value (*in)[3], (*mid)[3], (*pix)[3], (*out)[3]; | |
38 | char nl; | |
39 | int maxval, i, j, iwide, ihigh, owide, ohigh; | |
40 | unsigned irow, icol, orow, ocol; | |
41 | ||
42 | #if defined(WIN32) || defined(DJGPP) | |
43 | if (setmode(0,O_BINARY) < 0) perror("setmode(0)"); | |
44 | if (setmode(1,O_BINARY) < 0) perror("setmode(1)"); | |
45 | #endif | |
46 | ifp = stdin; | |
47 | ofp = stdout; | |
48 | if (fscanf (ifp, "P6 %d %d %d%c", &iwide, &ihigh, &maxval, &nl) != 4 | |
49 | || abs(iwide - ihigh) > 1) { | |
50 | fprintf (stderr, "Input is not a Fuji image processed by dcraw.\n"); | |
51 | exit(1); | |
52 | } | |
53 | i = (maxval > 255) ? 16 : 8; | |
54 | j = 8 * sizeof (value); | |
55 | if (i != j) { | |
56 | fprintf (stderr, "Input is %d-bit, fujiturn is %d-bit\n", i, j); | |
57 | exit(1); | |
58 | } | |
59 | in = calloc (iwide, sizeof *in); | |
60 | merror (in, "input array"); | |
61 | fread (in, iwide, sizeof *in, ifp); | |
62 | for (i = 0; i < iwide; i++) | |
63 | if (in[i][0] || in[i][1] || in[i][2]) break; | |
64 | ohigh = (iwide - i) * 2 - 4; | |
65 | for (i = iwide; --i;) | |
66 | if (in[i][0] || in[i][1] || in[i][2]) break; | |
67 | owide = i; | |
68 | mid = calloc (ohigh * owide, sizeof *mid); | |
69 | merror (mid, "middle array"); | |
70 | for (irow = 0; irow < ihigh; irow++) { | |
71 | for (icol = 0; icol < iwide; icol++) { | |
72 | orow = irow + icol - owide + 5; | |
73 | ocol = (icol - irow + owide - 1)/2; | |
74 | if (orow < ohigh && ocol < owide) | |
75 | for (i = 0; i < 3; i++) | |
76 | mid[orow*owide+ocol][i] = ntohs(in[icol][i]); | |
77 | } | |
78 | fread (in, iwide, sizeof *in, ifp); | |
79 | } | |
80 | free(in); | |
81 | out = calloc (2*owide, sizeof *out); | |
82 | merror (out, "output array"); | |
83 | fprintf (ofp, "P6\n%d %d\n%d\n", owide*2, ohigh, maxval); | |
84 | for (orow = 0; orow < ohigh; orow++) { | |
85 | for (ocol = 0; ocol < owide*2; ocol++) { | |
86 | pix = mid + orow*owide + ocol/2; | |
87 | if ((orow+ocol) & 1) { | |
88 | if (orow-1 < ohigh-2 && ocol-1 < owide*2-2) | |
89 | for (i = 0; i < 3; i++) | |
90 | out[ocol][i] = htons ( | |
91 | ( pix[-owide][i] + pix[0-(orow&1)][i] + | |
92 | pix[ owide][i] + pix[1-(orow&1)][i] ) >> 2); | |
93 | } else | |
94 | for (i = 0; i < 3; i++) | |
95 | out[ocol][i] = htons(pix[0][i]); | |
96 | } | |
97 | fwrite (out, 2*owide, 3*sizeof (value), ofp); | |
98 | } | |
99 | free(mid); | |
100 | free(out); | |
101 | return 0; | |
102 | } |