fujiturn.c

00001 /*
00002    fujiturn.c by Dave Coffin
00003 
00004    UNIX filter to correct the 45-degree rotation in images from
00005    Fuji digital cameras.  Compile with -D_16BIT to rotate 48-bit
00006    PPM images.  Sample usage:
00007 
00008    dcraw -c -j dscf0000.raf | fujiturn | pnmscale 0.70710678 > dscf0000.ppm
00009 
00010    $Revision: 1.1 $
00011    $Date: 2005/06/27 14:07:24 $
00012 
00013  */
00014 
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <fcntl.h>
00018 
00019 #ifdef _16BIT
00020 typedef unsigned short value;
00021 #else
00022 typedef unsigned char value;
00023 #define ntohs(x) (x)
00024 #define htons(x) (x)
00025 #endif
00026 
00027 void merror (void *ptr, char *what)
00028 {
00029   if (ptr) return;
00030   fprintf (stderr, "Not enough memory for %s\n", what);
00031   exit(1);
00032 }
00033 
00034 int main()
00035 {
00036   FILE *ifp, *ofp;
00037   value (*in)[3], (*mid)[3], (*pix)[3], (*out)[3];
00038   char nl;
00039   int maxval, i, j, iwide, ihigh, owide, ohigh;
00040   unsigned irow, icol, orow, ocol;
00041 
00042 #if defined(WIN32) || defined(DJGPP)
00043   if (setmode(0,O_BINARY) < 0) perror("setmode(0)");
00044   if (setmode(1,O_BINARY) < 0) perror("setmode(1)");
00045 #endif
00046   ifp = stdin;
00047   ofp = stdout;
00048   if (fscanf (ifp, "P6 %d %d %d%c", &iwide, &ihigh, &maxval, &nl) != 4
00049     || abs(iwide - ihigh) > 1) {
00050     fprintf (stderr, "Input is not a Fuji image processed by dcraw.\n");
00051     exit(1);
00052   }
00053   i = (maxval > 255) ? 16 : 8;
00054   j = 8 * sizeof (value);
00055   if (i != j) {
00056     fprintf (stderr, "Input is %d-bit, fujiturn is %d-bit\n", i, j);
00057     exit(1);
00058   }
00059   in = calloc (iwide, sizeof *in);
00060   merror (in, "input array");
00061   fread (in, iwide, sizeof *in, ifp);
00062   for (i = 0; i < iwide; i++)
00063     if (in[i][0] || in[i][1] || in[i][2]) break;
00064   ohigh = (iwide - i) * 2 - 4;
00065   for (i = iwide; --i;)
00066     if (in[i][0] || in[i][1] || in[i][2]) break;
00067   owide = i;
00068   mid = calloc (ohigh * owide, sizeof *mid);
00069   merror (mid, "middle array");
00070   for (irow = 0; irow < ihigh; irow++) {
00071     for (icol = 0; icol < iwide; icol++) {
00072       orow =  irow + icol - owide + 5;
00073       ocol = (icol - irow + owide - 1)/2;
00074       if (orow < ohigh && ocol < owide)
00075     for (i = 0; i < 3; i++)
00076       mid[orow*owide+ocol][i] = ntohs(in[icol][i]);
00077     }
00078     fread (in, iwide, sizeof *in, ifp);
00079   }
00080   free(in);
00081   out = calloc (2*owide, sizeof *out);
00082   merror (out, "output array");
00083   fprintf (ofp, "P6\n%d %d\n%d\n", owide*2, ohigh, maxval);
00084   for (orow = 0; orow < ohigh; orow++) {
00085     for (ocol = 0; ocol < owide*2; ocol++) {
00086       pix = mid + orow*owide + ocol/2;
00087       if ((orow+ocol) & 1) {
00088         if (orow-1 < ohigh-2 && ocol-1 < owide*2-2)
00089       for (i = 0; i < 3; i++)
00090         out[ocol][i] = htons (
00091         ( pix[-owide][i] + pix[0-(orow&1)][i] +
00092           pix[ owide][i] + pix[1-(orow&1)][i] ) >> 2);
00093       } else
00094     for (i = 0; i < 3; i++)
00095       out[ocol][i] = htons(pix[0][i]);
00096     }
00097     fwrite (out, 2*owide, 3*sizeof (value), ofp);
00098   }
00099   free(mid);
00100   free(out);
00101   return 0;
00102 }

Generated on Sat Jan 27 11:36:13 2007 for libopenraw by  doxygen 1.4.7