103 lines
2.7 KiB
C
103 lines
2.7 KiB
C
/*
|
|
fujiturn.c by Dave Coffin
|
|
|
|
UNIX filter to correct the 45-degree rotation in images from
|
|
Fuji digital cameras. Compile with -D_16BIT to rotate 48-bit
|
|
PPM images. Sample usage:
|
|
|
|
dcraw -c -j dscf0000.raf | fujiturn | pnmscale 0.70710678 > dscf0000.ppm
|
|
|
|
$Revision: 1.6 $
|
|
$Date: 2005/04/29 16:35:42 $
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
|
|
#ifdef _16BIT
|
|
typedef unsigned short value;
|
|
#else
|
|
typedef unsigned char value;
|
|
#define ntohs(x) (x)
|
|
#define htons(x) (x)
|
|
#endif
|
|
|
|
void merror (void *ptr, char *what)
|
|
{
|
|
if (ptr) return;
|
|
fprintf (stderr, "Not enough memory for %s\n", what);
|
|
exit(1);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
FILE *ifp, *ofp;
|
|
value (*in)[3], (*mid)[3], (*pix)[3], (*out)[3];
|
|
char nl;
|
|
int maxval, i, j, iwide, ihigh, owide, ohigh;
|
|
unsigned irow, icol, orow, ocol;
|
|
|
|
#if defined(WIN32) || defined(DJGPP)
|
|
if (setmode(0,O_BINARY) < 0) perror("setmode(0)");
|
|
if (setmode(1,O_BINARY) < 0) perror("setmode(1)");
|
|
#endif
|
|
ifp = stdin;
|
|
ofp = stdout;
|
|
if (fscanf (ifp, "P6 %d %d %d%c", &iwide, &ihigh, &maxval, &nl) != 4
|
|
|| abs(iwide - ihigh) > 1) {
|
|
fprintf (stderr, "Input is not a Fuji image processed by dcraw.\n");
|
|
exit(1);
|
|
}
|
|
i = (maxval > 255) ? 16 : 8;
|
|
j = 8 * sizeof (value);
|
|
if (i != j) {
|
|
fprintf (stderr, "Input is %d-bit, fujiturn is %d-bit\n", i, j);
|
|
exit(1);
|
|
}
|
|
in = calloc (iwide, sizeof *in);
|
|
merror (in, "input array");
|
|
fread (in, iwide, sizeof *in, ifp);
|
|
for (i = 0; i < iwide; i++)
|
|
if (in[i][0] || in[i][1] || in[i][2]) break;
|
|
ohigh = (iwide - i) * 2 - 4;
|
|
for (i = iwide; --i;)
|
|
if (in[i][0] || in[i][1] || in[i][2]) break;
|
|
owide = i;
|
|
mid = calloc (ohigh * owide, sizeof *mid);
|
|
merror (mid, "middle array");
|
|
for (irow = 0; irow < ihigh; irow++) {
|
|
for (icol = 0; icol < iwide; icol++) {
|
|
orow = irow + icol - owide + 5;
|
|
ocol = (icol - irow + owide - 1)/2;
|
|
if (orow < ohigh && ocol < owide)
|
|
for (i = 0; i < 3; i++)
|
|
mid[orow*owide+ocol][i] = ntohs(in[icol][i]);
|
|
}
|
|
fread (in, iwide, sizeof *in, ifp);
|
|
}
|
|
free(in);
|
|
out = calloc (2*owide, sizeof *out);
|
|
merror (out, "output array");
|
|
fprintf (ofp, "P6\n%d %d\n%d\n", owide*2, ohigh, maxval);
|
|
for (orow = 0; orow < ohigh; orow++) {
|
|
for (ocol = 0; ocol < owide*2; ocol++) {
|
|
pix = mid + orow*owide + ocol/2;
|
|
if ((orow+ocol) & 1) {
|
|
if (orow-1 < ohigh-2 && ocol-1 < owide*2-2)
|
|
for (i = 0; i < 3; i++)
|
|
out[ocol][i] = htons (
|
|
( pix[-owide][i] + pix[0-(orow&1)][i] +
|
|
pix[ owide][i] + pix[1-(orow&1)][i] ) >> 2);
|
|
} else
|
|
for (i = 0; i < 3; i++)
|
|
out[ocol][i] = htons(pix[0][i]);
|
|
}
|
|
fwrite (out, 2*owide, 3*sizeof (value), ofp);
|
|
}
|
|
free(mid);
|
|
free(out);
|
|
return 0;
|
|
}
|