1 // ppmzip.cpp
2 
3 #include "stdafx.h"
4 
5 #define COMP   1
6 #define DECOMP 2
7 
8 #define TRY_ROT(a) (rot?a^0xff:a)
9 
10 /* PPMDi getc/putc bridge */
PPMDI(FILE * f)11 PPMDI::PPMDI(FILE *f)
12 {
13    file = f;
14    count = 0;
15 }
16 
_putc(char c)17 void PPMDI::_putc(char c)
18 {
19    putc (c,file);
20    count++;
21 }
22 
_getc()23 int PPMDI::_getc()
24 {
25    count++;
26 #ifdef _DEBUG
27    int a = count;
28    a = getc(file);
29    return a;
30 #else
31    return getc(file);
32 #endif
33 }
34 
getCount()35 int PPMDI::getCount()
36 {
37    return count;
38 }
39 
40 /* copy-paste from xmilldata.cpp etc */
41 typedef struct {
42    int size;
43    int order;
44 } level_settings;
45 
46 #define XMILL_PPMDI_IDXS            19
47 
48 level_settings ppmsettings[XMILL_PPMDI_IDXS] = {
49   {1,6},
50   {1,7},
51   {1,8},
52   {1,9},
53   {4,9},
54   {1,10},
55   {2,10},
56   {5,10},
57   {6,10},
58   {8,10},
59   {10,10},
60   {20,10},
61   {1,12},
62   {2,12},
63   {1,16},
64   {2,16},
65   {3,16},
66   {4,16},
67   {8,16}
68 };
69 
70 /* main program, contains all PPMDi (de)compress API calls */
71 #ifdef WIN32
main(int argc,char ** argv)72 int _cdecl main(int argc,char **argv)
73 #else
74 int main(int argc,char **argv)
75 #endif
76 {
77    int action = COMP;
78    FILE* outfile = stdout;
79    FILE* infile = stdin;
80    int c, stat = 0, size = 10, order = 6, i = 0, c1;
81    PPM_ENCODER* enc = NULL;
82    PPM_DECODER* dec = NULL;
83    PPMDIData *data = NULL;
84    PPMDI *f = NULL;
85    bool rot = false, skip4 = false;
86 
87    /* check arguments */
88    if (argc > 1) {
89       if (toupper(argv[1][0]) == 'D') {
90          action = DECOMP;
91       } else if (toupper(argv[1][0]) == 'C') {
92          action = COMP;
93       }
94    }
95 
96    if (argc > 2) {
97       infile = fopen(argv[2], "r");
98    }
99 
100    if (argc > 3) {
101       outfile = fopen(argv[3], "wb");
102    }
103 
104    if (argc > 5) {
105       size = atoi(argv[4]);
106       order = atoi(argv[5]);
107    }
108 
109    if (argc > 6) {
110       skip4 = (toupper(argv[6][0]) == 'T');
111       rot = argv[6][1];
112    }
113 
114 #ifdef WIN32
115    _setmode(_fileno(infile), _O_BINARY);
116    _setmode(_fileno(outfile), _O_BINARY);
117 #else
118    /* how do I implement this on Unix?? */
119 #endif
120 
121    switch (action) {
122       case COMP:
123          /* compress the file */
124          f = new PPMDI(outfile);
125          data = new PPMDIData(f);
126          data->getAlloc(size);
127          enc = new PPM_ENCODER (size,order,data);
128          data->ariInitEncoder();
129          while ((c = getc(infile)) != EOF) {
130             enc->EncodeChar(TRY_ROT(c));
131             i++;
132          }
133          enc->EncodeChar(EOF);
134          data->ariFlushEncoder();
135          break;
136 
137       case DECOMP:
138          /* decompress the file */
139          if (skip4) {
140             /* skip first four Bytes & read size/order from the last one */
141             for (int j=0; j<4; j++) {
142                c1 = getc(infile);
143             }
144             size = ppmsettings[c1].size;
145             order = ppmsettings[c1].order;
146          }
147          f = new PPMDI(infile);
148          data = new PPMDIData(f);
149          data->getAlloc(size);
150          dec = new PPM_DECODER (size,order,data);
151          data->ariInitDecoder();
152          while (TRUE) {
153             if ((c1 = dec->DecodeChar()) == EOF) {
154                goto cleanup;
155             }
156             i++;
157             putc(TRY_ROT(c1), outfile);
158          }
159 
160          break;
161 
162       default:
163          stat = 1;
164          goto cleanup;
165    }
166 
167 cleanup:
168    if (stat == 0 && outfile != stdout && f) {
169       printf ("(de)compressed %ld Bytes to %ld Bytes\n", f->getCount(), i);
170    }
171 
172    if (f) delete f;
173    if (data) delete data;
174    if (enc) delete enc;
175    if (dec) delete dec;
176    if (infile) fclose(infile);
177    if (outfile) fclose(outfile);
178 
179    return stat;
180 }
181