Swap endianess of PNM files, fist version master
authorJean-Michel Nirgal Vourgère <jmv@nirgal.com>
Wed, 12 Mar 2008 15:04:23 +0000 (15:04 +0000)
committerJean-Michel Nirgal Vourgère <jmv@nirgal.com>
Wed, 12 Mar 2008 15:04:23 +0000 (15:04 +0000)
swappnm.c [new file with mode: 0644]

diff --git a/swappnm.c b/swappnm.c
new file mode 100644 (file)
index 0000000..845fe3c
--- /dev/null
+++ b/swappnm.c
@@ -0,0 +1,106 @@
+/* 
+ * This small utility convert big endian to little endian format
+ * the pnm image files. This is only usefull for file that have a
+ * resolution higher than 1 byte per RGB componant, such as
+ * 48bits/pixel outputed by some scanner such as CanoScanFS2710:
+ *     scanimage --resolution=2720 --mode Raw > image.pnm
+ *     swappnm image.pnm fixed_image.pnm
+ *     convert image.pnm image.jpg
+ *
+ * Compile with gcc swappnm.c -o swappnm
+ *
+ * This is free software.
+ */
+
+#include <stdio.h>
+#include <stdio.h>
+
+#define BUF_SIZE 256
+
+void print_usage() {
+       puts("parameters: filein fileout\n");
+}
+
+// Reads a line
+void readline(FILE* file, char* buf, int bufsize) {
+       char c;
+       do {
+               c=fgetc(file);
+               if (c=='\n' || c=='\r' || !--bufsize || feof(file))
+                       c = 0;
+               *(buf++) = c;
+       } while (c);
+}
+int main(int argc, char* argv[]) {
+       
+       char buf[BUF_SIZE];
+       int w, h, maxval;
+
+       if (argc!=3) {
+               print_usage();
+               return 1;
+       }
+       FILE *fin=fopen(argv[1], "rb");
+       if (!fin) {
+               perror("Can't open input file");
+               return 1;
+       }
+       FILE *fout=fopen(argv[2], "w+b");
+       if (!fout) {
+               perror("Can't open output file");
+               return 1;
+       }
+       
+       readline(fin, buf, BUF_SIZE);
+       if (strcmp(buf, "P6")) {
+               fprintf(stderr, "Unsupported file format %s\n", buf);
+               return 1;
+       }
+       fputs(buf, fout);
+       fputc('\n', fout);
+
+       do {
+               readline(fin, buf, BUF_SIZE);
+               fputs(buf, fout);
+               fputc('\n', fout);
+       } while (buf[0]=='#' || buf[0]==0);
+       sscanf(buf, "%d %d", &w, &h);
+
+       do {
+               readline(fin, buf, BUF_SIZE);
+               fputs(buf, fout);
+               fputc('\n', fout);
+       } while (buf[0]=='#' || buf[0]==0);
+       sscanf(buf, "%d", &maxval);
+       
+       if (maxval<(1<<8)) {
+               fprintf(stderr, "Color space is one byte encoded. Nothing to swap!\n");
+               return 1;
+       }
+       if (maxval>=(1<<16)) {
+               fprintf(stderr, "Color space is more than two bytes encoded. Not implemented.");
+               return 1;
+       }
+
+       printf("Endian swaping %s to %s (w=%d, h=%d, maxval=%d)\n", argv[1], argv[2], w, h,maxval);
+
+       int i, j, k;
+       unsigned short v;
+       for (i=0; i<w; ++i)
+               for (j=0; j<h; ++j)
+                       for (k=0; k<3/*rgb*/; ++k) {
+                               if (fread(&v, 2, 1, fin)!=1) {
+                                       fprintf(stderr, "Read failed\n");
+                                       return 1;
+                               }
+//                             printf("%x",v);
+                               v = ((v&0x00ff)<<8)|((v&0xff00)>>8);
+                               if (fwrite(&v, 2, 1, fout)!=1) {
+                                       fprintf(stderr, "Write failed\n");
+                                       return 1;
+                               }
+                       }
+       fclose (fin);
+       fclose (fout);
+       return 0;
+}