- updated to 8.43 from 2006/11/21, some additional files
authorPaweł Gołaszewski <blues@pld-linux.org>
Thu, 23 Nov 2006 12:27:03 +0000 (12:27 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    clean_crw.c -> 1.1
    fuji_green.c -> 1.1
    fujiturn.c -> 1.1

clean_crw.c [new file with mode: 0644]
fuji_green.c [new file with mode: 0644]
fujiturn.c [new file with mode: 0644]

diff --git a/clean_crw.c b/clean_crw.c
new file mode 100644 (file)
index 0000000..729b1b0
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+   Because they are parsed from the end, Canon CRW files
+   become unreadable if garbage data is appended to them, as
+   often happens when files are recovered from damaged media.
+   This program truncates CRW files to the correct size.
+
+   Copyright 2005 by Dave Coffin, dcoffin a cybercom o net
+   Free for all uses.
+
+   $Revision$
+   $Date$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+unsigned char *buffer;
+
+int get4 (int i)
+{
+  if (buffer[0] == 'I')
+    return buffer[i+3] << 24 | buffer[i+2] << 16 | buffer[i+1] << 8 | buffer[i];
+  else
+    return buffer[i] << 24 | buffer[i+1] << 16 | buffer[i+2] << 8 | buffer[i+3];
+}
+
+int main (int argc, char **argv)
+{
+  int arg, size, end, diff, status=1;
+  unsigned char *fname;
+  FILE *fp;
+
+  if (argc == 1)
+    fprintf (stderr, "Usage:  %s crw_0001.crw crw_0002.crw ...\n", argv[0]);
+
+  for (arg=1; arg < argc; arg++) {
+    status = 1;
+    fp = fopen (argv[arg], "rb");
+    fseek (fp, 0, SEEK_END);
+    size = ftell(fp);
+    buffer = malloc (size + strlen(argv[arg]) + 10);
+    if (!buffer) {
+      fprintf (stderr, "Cannot allocate memory!\n");
+      return 2;
+    }
+    fname = buffer + size;
+    sprintf (fname, "%s.clean", argv[arg]);
+    fseek (fp, 0, SEEK_SET);
+    fread (buffer, 1, size, fp);
+    fclose (fp);
+    if (strncmp (buffer, "II\x1a\0\0\0HEAPCCDR", 14) &&
+       strncmp (buffer, "MM\0\0\0\x1aHEAPCCDR", 14)) {
+      fprintf (stderr, "%s is not a CRW file!\n", argv[arg]);
+      free (buffer);
+      continue;
+    }
+    for (end=size; end > 0xa0000; end--) {
+      diff = end - get4(end-4);
+      if (diff > 50 && diff < 120 && diff % 10 == 2) {
+       status = 0;
+       break;
+      }
+    }
+    if (status)
+      fprintf (stderr, "Failed to clean %s\n", argv[arg]);
+    else {
+      if ((fp = fopen (fname, "wb"))) {
+       fprintf (stderr, "Writing %s\n", fname);
+       fwrite (buffer, 1, end, fp);
+       fclose (fp);
+      } else {
+       perror (fname);
+       status = 1;
+      }
+    }
+    free (buffer);
+  }
+  return status;
+}
diff --git a/fuji_green.c b/fuji_green.c
new file mode 100644 (file)
index 0000000..985849f
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+   fuji_green -- read Fuji green pixels
+
+   $Revision$
+   $Date$
+ */
+
+#include <ctype.h>
+#include <math.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ushort UshORt
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+
+FILE *ifp;
+short order;
+char *ifname, make[64], model[64];
+int data_offset, raw_height, raw_width, height, width;
+int fuji_layout, fuji_secondary, use_secondary=0, verbose=0;
+ushort *image;
+void (*load_raw)();
+float bright=1.0;
+void write_ppm(FILE *);
+void (*write_fun)(FILE *) = write_ppm;
+jmp_buf failure;
+
+#define CLASS
+
+void CLASS merror (void *ptr, char *where)
+{
+  if (ptr) return;
+  fprintf (stderr, "%s: Out of memory in %s\n", ifname, where);
+  longjmp (failure, 1);
+}
+
+ushort CLASS get2()
+{
+  uchar a, b;
+
+  a = fgetc(ifp);
+  b = fgetc(ifp);
+  if (order == 0x4949)         /* "II" means little-endian */
+    return a + (b << 8);
+  else                         /* "MM" means big-endian */
+    return (a << 8) + b;
+}
+
+int CLASS get4()
+{
+  uchar a, b, c, d;
+
+  a = fgetc(ifp);
+  b = fgetc(ifp);
+  c = fgetc(ifp);
+  d = fgetc(ifp);
+  if (order == 0x4949)
+    return a + (b << 8) + (c << 16) + (d << 24);
+  else
+    return (a << 24) + (b << 16) + (c << 8) + d;
+}
+
+/*
+   Faster than calling get2() multiple times.
+ */
+void CLASS read_shorts (ushort *pixel, int count)
+{
+  fread (pixel, 2, count, ifp);
+  if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
+    swab (pixel, pixel, count*2);
+}
+
+void CLASS fuji_load_raw()
+{
+  ushort *pixel, *img;
+  int row, col;
+
+  pixel = calloc (raw_width, 2);
+  merror (pixel, "fuji_load_raw()");
+  for (row=0; row < height; row++)
+    if (fuji_layout) {
+      read_shorts (image+row*width, width);
+      fseek (ifp, (raw_width*2 - width)*2, SEEK_CUR);
+    } else {
+      read_shorts (pixel, raw_width);
+      for (img=image+row*width, col=0; col < width; col++)
+       img[col] = pixel[col*2+1];
+    }
+  free (pixel);
+}
+
+void CLASS parse_fuji (int offset)
+{
+  unsigned entries, tag, len, save;
+
+  fseek (ifp, offset, SEEK_SET);
+  entries = get4();
+  if (entries > 255) return;
+  while (entries--) {
+    tag = get2();
+    len = get2();
+    save = ftell(ifp);
+    if (tag == 0x100) {
+      raw_height = get2();
+      raw_width  = get2();
+    } else if (tag == 0x121) {
+      height = get2();
+      width  = get2();
+    } else if (tag == 0x130)
+      fuji_layout = fgetc(ifp) >> 7;
+    fseek (ifp, save+len, SEEK_SET);
+  }
+  if (fuji_layout) {
+    height *= 2;
+    width  /= 2;
+  }
+}
+
+void CLASS parse_tiff (int base)
+{
+  int doff, entries, tag, type, len, save;
+
+  fseek (ifp, base, SEEK_SET);
+  order = get2();
+  get2();                              /* Should be 42 for standard TIFF */
+  while ((doff = get4())) {
+    fseek (ifp, doff+base, SEEK_SET);
+    entries = get2();
+    while (entries--) {
+      tag  = get2();
+      type = get2();
+      len  = get4();
+      save = ftell(ifp)+4;
+      fseek (ifp, base+get4(), SEEK_SET);
+      switch (tag) {
+       case 0x10f:                     /* Make tag */
+         fgets (make, 64, ifp);
+         break;
+       case 0x110:                     /* Model tag */
+         fgets (model, 64, ifp);
+      }
+      fseek (ifp, save, SEEK_SET);
+    }
+  }
+}
+
+int CLASS identify()
+{
+  char head[32], *c;
+  int thumb_offset;
+
+  make[0] = model[0] = 0;
+  data_offset = raw_height = raw_width = height = width = 0;
+  fuji_secondary = 0;
+
+  order = 0x4d4d;
+  fread (head, 1, 32, ifp);
+  if (memcmp (head, "FUJIFILM", 8)) return 1;
+  fseek (ifp, 84, SEEK_SET);
+  thumb_offset = get4();
+  fseek (ifp, 92, SEEK_SET);
+  parse_fuji (get4());
+  if (thumb_offset > 120) {
+    fseek (ifp, 120, SEEK_SET);
+    fuji_secondary = get4() && 1;
+  }
+  fseek (ifp, 100, SEEK_SET);
+  data_offset = get4();
+  parse_tiff (thumb_offset+12);
+  c = model + strlen(model);           /* Remove trailing spaces */
+  while (*--c == ' ') *c = 0;
+  if (!strcmp(model,"FinePix S5100") ||
+      !strcmp(model,"FinePix S5500")) return 1;
+  load_raw = fuji_load_raw;
+  if (!strcmp(model+7,"S2Pro")) {
+    strcpy (model+7," S2Pro");
+    height = 2144;
+    width  = 2880;
+  }
+  data_offset += (raw_height - height + 1)*raw_width - width;
+  if (fuji_secondary)
+    data_offset += use_secondary * ( strcmp(model+7," S3Pro")
+               ? (raw_width *= 2) : raw_height*raw_width*2 );
+  data_offset += fuji_layout*raw_width*2;
+  width >>= !fuji_layout;
+  height >>= fuji_layout;
+  fseek (ifp, data_offset, SEEK_SET);
+  return 0;
+}
+
+void CLASS write_ppm (FILE *ofp)
+{
+  int i, size, val, total, histogram[0x2000];
+  float white, r;
+  uchar lut[0x10000];
+
+  memset (histogram, 0, sizeof histogram);
+  size = width * height;
+  for (i = 0; i < size; i++)
+    histogram[image[i] >> 4]++;
+  i = size * 0.01;                     /* 99th percentile white point */
+  for (val=0x2000, total=0; --val; )
+    if ((total += histogram[val]) > i) break;
+  white = (val << 4) / bright;
+
+  for (i=0; i < 0x10000; i++) {
+    r = i / white;
+    val = (r <= 0.018 ? r*4.5 : pow(r,0.45)*1.099-0.099) * 256;
+    if (val > 255) val = 255;
+    lut[i] = val;
+  }
+  fprintf (ofp, "P5\n%d %d\n255\n", width, height);
+  for (i=0; i < size; i++)
+    fputc (lut[image[i]], ofp);
+}
+
+void CLASS write_raw16 (FILE *ofp)
+{
+  if (ntohs(0x1234) != 0x1234)
+    swab (image, image, width*height*2);
+  fwrite (image, width*height, 2, ofp);
+}
+
+void CLASS write_ppm16 (FILE *ofp)
+{
+  fprintf (ofp, "P5\n%d %d\n%d\n", width, height, 65535);
+  write_raw16 (ofp);
+}
+
+void CLASS write_psd (FILE *ofp)
+{
+  char head[] = {
+    '8','B','P','S',           /* signature */
+    0,1,0,0,0,0,0,0,           /* version and reserved */
+    0,1,                       /* number of channels */
+    0,0,0,0,                   /* height, big-endian */
+    0,0,0,0,                   /* width, big-endian */
+    0,16,                      /* 16-bit color */
+    0,1,                       /* mode (1=grey, 3=rgb) */
+    0,0,0,0,                   /* color mode data */
+    0,0,0,0,                   /* image resources */
+    0,0,0,0,                   /* layer/mask info */
+    0,0 };                     /* no compression */
+  int hw[2];
+
+  hw[0] = htonl(height*2);     /* write the header */
+  hw[1] = htonl(width*2);
+  memcpy (head+14, hw, sizeof hw);
+  fwrite (head, 40, 1, ofp);
+  write_raw16 (ofp);
+}
+
+int CLASS main (int argc, char **argv)
+{
+  int arg, status=0;
+  int identify_only=0, write_to_stdout=0;
+  char opt, *ofname, *cp;
+  const char *write_ext = ".pgm";
+  FILE *ofp = stdout;
+
+  if (argc == 1) {
+    fprintf (stderr,
+    "\nFuji Green channel output"
+    "\nby Dave Coffin, dcoffin a cybercom o net"
+    "\n\nUsage:  %s [options] file1 file2 ...\n"
+    "\nValid options:"
+    "\n-v        Print verbose messages"
+    "\n-c        Write image data to standard output"
+    "\n-i        Identify files without decoding them"
+    "\n-s        Use secondary pixels if available"
+    "\n-b <num>  Set brightness (default = 1.0)"
+    "\n-2        Write  8-bit non-linear PGM (default)"
+    "\n-4        Write 16-bit linear PGM"
+    "\n-3        Write 16-bit linear PSD (Adobe Photoshop)"
+    "\n\n", argv[0]);
+    return 1;
+  }
+  argv[argc] = "";
+  for (arg=1; argv[arg][0] == '-'; ) {
+    opt = argv[arg++][1];
+    if (strchr ("b", opt) && !isdigit(argv[arg][0])) {
+      fprintf (stderr, "\"-%c\" requires a numeric argument.\n", opt);
+      return 1;
+    }
+    switch (opt) {
+      case 'v':  verbose           = 1;  break;
+      case 'i':  identify_only     = 1;  break;
+      case 'c':  write_to_stdout   = 1;  break;
+      case 's':  use_secondary     = 1;  break;
+      case 'b':  bright = atof(argv[arg++]);  break;
+      case '2':  write_fun = write_ppm;    break;
+      case '4':  write_fun = write_ppm16;  break;
+      case '3':  write_fun = write_psd;  write_ext = ".psd";  break;
+      default:
+       fprintf (stderr, "Unknown option \"-%c\".\n", opt);
+       return 1;
+    }
+  }
+  if (arg == argc) {
+    fprintf (stderr, "No files to process.\n");
+    return 1;
+  }
+  if (write_to_stdout) {
+    if (isatty(1)) {
+      fprintf (stderr, "Will not write an image to the terminal!\n");
+      return 1;
+    }
+#if defined(WIN32) || defined(DJGPP)
+    if (setmode(1,O_BINARY) < 0) {
+      perror("setmode()");
+      return 1;
+    }
+#endif
+  }
+  for ( ; arg < argc; arg++) {
+    status = 1;
+    image = NULL;
+    if (setjmp (failure)) {
+      if (fileno(ifp) > 2) fclose (ifp);
+      if (fileno(ofp) > 2) fclose (ofp);
+      if (image) free (image);
+      status = 1;
+      continue;
+    }
+    ifname = argv[arg];
+    if (!(ifp = fopen (ifname, "rb"))) {
+      perror (ifname);
+      continue;
+    }
+    if ((status = identify())) {
+      fprintf (stderr, "%s: unsupported file format.\n", ifname);
+      fclose (ifp);
+      continue;
+    }
+    if (identify_only) {
+      fprintf (stderr, "%s is a %s %s image.\n", ifname, make, model);
+      fclose (ifp);
+      continue;
+    }
+    image = calloc (height * width, sizeof *image);
+    merror (image, "main()");
+    if (verbose)
+      fprintf (stderr,
+       "Loading %s %s image from %s...\n", make, model, ifname);
+    (*load_raw)();
+    fclose (ifp);
+    ofname = malloc (strlen(ifname) + 16);
+    merror (ofname, "main()");
+    if (write_to_stdout)
+      strcpy (ofname, "standard output");
+    else {
+      strcpy (ofname, ifname);
+      if ((cp = strrchr (ofname, '.'))) *cp = 0;
+      strcat (ofname, write_ext);
+      ofp = fopen (ofname, "wb");
+      if (!ofp) {
+       status = 1;
+       perror (ofname);
+       goto cleanup;
+      }
+    }
+    if (verbose)
+      fprintf (stderr, "Writing data to %s...\n", ofname);
+    (*write_fun)(ofp);
+    if (ofp != stdout)
+      fclose (ofp);
+cleanup:
+    free (ofname);
+    free (image);
+  }
+  return status;
+}
diff --git a/fujiturn.c b/fujiturn.c
new file mode 100644 (file)
index 0000000..feb367a
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+   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$
+   $Date$
+
+ */
+
+#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;
+}
This page took 0.061747 seconds and 4 git commands to generate.