2 fujiturn.c by Dave Coffin
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:
8 dcraw -c -j dscf0000.raf | fujiturn | pnmscale 0.70710678 > dscf0000.ppm
20 typedef unsigned short value;
22 typedef unsigned char value;
27 void merror (void *ptr, char *what)
30 fprintf (stderr, "Not enough memory for %s\n", what);
37 value (*in)[3], (*mid)[3], (*pix)[3], (*out)[3];
39 int maxval, i, j, iwide, ihigh, owide, ohigh;
40 unsigned irow, icol, orow, ocol;
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)");
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");
53 i = (maxval > 255) ? 16 : 8;
54 j = 8 * sizeof (value);
56 fprintf (stderr, "Input is %d-bit, fujiturn is %d-bit\n", i, j);
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;
66 if (in[i][0] || in[i][1] || in[i][2]) break;
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]);
78 fread (in, iwide, sizeof *in, ifp);
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);
94 for (i = 0; i < 3; i++)
95 out[ocol][i] = htons(pix[0][i]);
97 fwrite (out, 2*owide, 3*sizeof (value), ofp);