Swap endianess of PNM files, fist version
[swappnm.git] / swappnm.c
1 /* 
2  * This small utility convert big endian to little endian format
3  * the pnm image files. This is only usefull for file that have a
4  * resolution higher than 1 byte per RGB componant, such as
5  * 48bits/pixel outputed by some scanner such as CanoScanFS2710:
6  *      scanimage --resolution=2720 --mode Raw > image.pnm
7  *      swappnm image.pnm fixed_image.pnm
8  *      convert image.pnm image.jpg
9  *
10  * Compile with gcc swappnm.c -o swappnm
11  *
12  * This is free software.
13  */
14
15 #include <stdio.h>
16 #include <stdio.h>
17
18 #define BUF_SIZE 256
19
20 void print_usage() {
21         puts("parameters: filein fileout\n");
22 }
23
24 // Reads a line
25 void readline(FILE* file, char* buf, int bufsize) {
26         char c;
27         do {
28                 c=fgetc(file);
29                 if (c=='\n' || c=='\r' || !--bufsize || feof(file))
30                         c = 0;
31                 *(buf++) = c;
32         } while (c);
33 }
34 int main(int argc, char* argv[]) {
35         
36         char buf[BUF_SIZE];
37         int w, h, maxval;
38
39         if (argc!=3) {
40                 print_usage();
41                 return 1;
42         }
43         FILE *fin=fopen(argv[1], "rb");
44         if (!fin) {
45                 perror("Can't open input file");
46                 return 1;
47         }
48         FILE *fout=fopen(argv[2], "w+b");
49         if (!fout) {
50                 perror("Can't open output file");
51                 return 1;
52         }
53         
54         readline(fin, buf, BUF_SIZE);
55         if (strcmp(buf, "P6")) {
56                 fprintf(stderr, "Unsupported file format %s\n", buf);
57                 return 1;
58         }
59         fputs(buf, fout);
60         fputc('\n', fout);
61
62         do {
63                 readline(fin, buf, BUF_SIZE);
64                 fputs(buf, fout);
65                 fputc('\n', fout);
66         } while (buf[0]=='#' || buf[0]==0);
67         sscanf(buf, "%d %d", &w, &h);
68
69         do {
70                 readline(fin, buf, BUF_SIZE);
71                 fputs(buf, fout);
72                 fputc('\n', fout);
73         } while (buf[0]=='#' || buf[0]==0);
74         sscanf(buf, "%d", &maxval);
75         
76         if (maxval<(1<<8)) {
77                 fprintf(stderr, "Color space is one byte encoded. Nothing to swap!\n");
78                 return 1;
79         }
80         if (maxval>=(1<<16)) {
81                 fprintf(stderr, "Color space is more than two bytes encoded. Not implemented.");
82                 return 1;
83         }
84
85         printf("Endian swaping %s to %s (w=%d, h=%d, maxval=%d)\n", argv[1], argv[2], w, h,maxval);
86
87         int i, j, k;
88         unsigned short v;
89         for (i=0; i<w; ++i)
90                 for (j=0; j<h; ++j)
91                         for (k=0; k<3/*rgb*/; ++k) {
92                                 if (fread(&v, 2, 1, fin)!=1) {
93                                         fprintf(stderr, "Read failed\n");
94                                         return 1;
95                                 }
96 //                              printf("%x",v);
97                                 v = ((v&0x00ff)<<8)|((v&0xff00)>>8);
98                                 if (fwrite(&v, 2, 1, fout)!=1) {
99                                         fprintf(stderr, "Write failed\n");
100                                         return 1;
101                                 }
102                         }
103         fclose (fin);
104         fclose (fout);
105         return 0;
106 }