1 /* compress.c --
2 
3    This file is part of the lzop file compressor.
4 
5    Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
6    All Rights Reserved.
7 
8    lzop and the LZO library are free software; you can redistribute them
9    and/or modify them under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of
11    the License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; see the file COPYING.
20    If not, write to the Free Software Foundation, Inc.,
21    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 
23    Markus F.X.J. Oberhumer
24    <markus@oberhumer.com>
25    http://www.oberhumer.com/opensource/lzop/
26  */
27 
28 
29 #include "conf.h"
30 
31 
32 /*************************************************************************
33 //
34 **************************************************************************/
35 
x_set_method(int m,int l)36 int x_set_method(int m, int l)
37 {
38     int r = -1;
39 
40 #if defined(WITH_LZO)
41     r = lzo_set_method(m,l);
42     if (r >= 0)
43         return r;
44 #endif
45 #if defined(WITH_NRV)
46     r = nrv_set_method(m,l);
47     if (r >= 0)
48         return r;
49 #endif
50 #if defined(WITH_ZLIB)
51     r = zlib_set_method(m,l);
52     if (r >= 0)
53         return r;
54 #endif
55 
56     UNUSED(r);
57     return -1;
58 }
59 
60 
x_get_method(header_t * h)61 int x_get_method(header_t *h)
62 {
63     int r = -1;
64 
65 #if defined(WITH_LZO)
66     r = lzo_get_method(h);
67     if (r >= 0)
68         return r;
69 #endif
70 #if defined(WITH_NRV)
71     r = nrv_get_method(h);
72     if (r >= 0)
73         return r;
74 #endif
75 #if defined(WITH_ZLIB)
76     r = zlib_get_method(h);
77     if (r >= 0)
78         return 0;
79 #endif
80 
81     UNUSED(r);
82     return 14;
83 }
84 
85 
86 /*************************************************************************
87 // memory setup
88 **************************************************************************/
89 
x_enter(const header_t * h)90 lzo_bool x_enter(const header_t *h)
91 {
92     if (h == NULL)
93     {
94         lzo_bool ok = 1;
95 #if defined(WITH_LZO)
96         ok &= lzo_enter(NULL);
97 #endif
98 #if defined(WITH_NRV)
99         ok &= nrv_enter(NULL);
100 #endif
101 #if defined(WITH_ZLIB)
102         ok &= zlib_enter(NULL);
103 #endif
104         return ok;
105     }
106 
107     switch (h->method)
108     {
109 #if defined(WITH_LZO)
110     case M_LZO1X_1:
111     case M_LZO1X_1_15:
112     case M_LZO1X_999:
113         return lzo_enter(h);
114 #endif
115 #if defined(WITH_NRV)
116     case M_NRV1A:
117     case M_NRV1B:
118     case M_NRV2A:
119     case M_NRV2B:
120         return nrv_enter(h);
121 #endif
122 #if defined(WITH_ZLIB)
123     case M_ZLIB:
124         return zlib_enter(h);
125 #endif
126     }
127     return 0;
128 }
129 
130 
x_leave(const header_t * h)131 void x_leave(const header_t *h)
132 {
133     if (h == NULL)
134     {
135 #if defined(WITH_ZLIB)
136         zlib_leave(NULL);
137 #endif
138 #if defined(WITH_NRV)
139         nrv_leave(NULL);
140 #endif
141 #if defined(WITH_LZO)
142         lzo_leave(NULL);
143 #endif
144         return;
145     }
146 
147     switch (h->method)
148     {
149 #if defined(WITH_LZO)
150     case M_LZO1X_1:
151     case M_LZO1X_1_15:
152     case M_LZO1X_999:
153         lzo_leave(h);
154         break;
155 #endif
156 #if defined(WITH_NRV)
157     case M_NRV1A:
158     case M_NRV1B:
159     case M_NRV2A:
160     case M_NRV2B:
161         nrv_leave(h);
162         break;
163 #endif
164 #if defined(WITH_ZLIB)
165     case M_ZLIB:
166         zlib_leave(h);
167         break;
168 #endif
169     }
170 }
171 
172 
173 /*************************************************************************
174 // compress a file
175 **************************************************************************/
176 
x_compress(file_t * fip,file_t * fop,header_t * h)177 lzo_bool x_compress(file_t *fip, file_t *fop, header_t *h)
178 {
179     lzo_bool ok = 0;
180 
181     init_compress_header(h,fip,fop);
182     switch (h->method)
183     {
184 #if defined(WITH_LZO)
185     case M_LZO1X_1:
186     case M_LZO1X_1_15:
187     case M_LZO1X_999:
188         lzo_init_compress_header(h);
189         break;
190 #endif
191 #if defined(WITH_NRV)
192     case M_NRV1A:
193     case M_NRV1B:
194     case M_NRV2A:
195     case M_NRV2B:
196         nrv_init_compress_header(h);
197         break;
198 #endif
199 #if defined(WITH_ZLIB)
200     case M_ZLIB:
201         zlib_init_compress_header(h);
202         break;
203 #endif
204     default:
205         fatal(fip,"Internal error");
206         break;
207     }
208 
209     if (!x_enter(h))
210         e_memory();
211 
212     if (opt_verbose > 1)
213     {
214         if (opt_unlink)
215             fprintf(con_term,"replacing %s with %s", fip->name, fop->name);
216         else
217             fprintf(con_term,"compressing %s into %s", fip->name, fop->name);
218         fflush(con_term);
219         set_err_nl(1);
220     }
221 
222     write_header(fop,h);
223 
224     fip->bytes_processed = fop->bytes_processed = 0;
225 
226     switch (h->method)
227     {
228 #if defined(WITH_LZO)
229     case M_LZO1X_1:
230     case M_LZO1X_1_15:
231     case M_LZO1X_999:
232         ok = lzo_compress(fip,fop,h);
233         break;
234 #endif
235 #if defined(WITH_NRV)
236     case M_NRV1A:
237     case M_NRV1B:
238     case M_NRV2A:
239     case M_NRV2B:
240         ok = nrv_compress(fip,fop,h);
241         break;
242 #endif
243 #if defined(WITH_ZLIB)
244     case M_ZLIB:
245         ok = zlib_compress(fip,fop,h);
246         break;
247 #endif
248     default:
249         fatal(fip,"Internal error");
250         ok = 0;
251         break;
252     }
253 
254     if (opt_cmd == CMD_COMPRESS && opt_verbose > 1)
255     {
256         fprintf(con_term, ok ? "\n" : " FAILED\n");
257         fflush(con_term);
258     }
259     set_err_nl(0);
260 
261     x_leave(h);
262     return ok;
263 }
264 
265 
266 /*************************************************************************
267 // decompress a file
268 **************************************************************************/
269 
x_decompress(file_t * fip,file_t * fop,const header_t * h,lzo_bool skip)270 lzo_bool x_decompress(file_t *fip, file_t *fop,
271                       const header_t *h, lzo_bool skip)
272 {
273     lzo_bool ok = 0;
274 
275     if (!x_enter(h))
276         e_memory();
277 
278     if (skip)
279     {
280         assert(opt_cmd != CMD_TEST);
281         assert(fop->fd < 0);
282         if (opt_cmd == CMD_DECOMPRESS && opt_verbose > 0)
283             fprintf(con_term,"skipping %s [%s]", fip->name, fop->name);
284         fflush(con_term);
285         set_err_nl(1);
286     }
287     else if (opt_cmd == CMD_DECOMPRESS && opt_verbose > 1)
288     {
289         if (opt_unlink)
290             fprintf(con_term,"restoring %s into %s", fip->name, fop->name);
291         else
292             fprintf(con_term,"decompressing %s into %s", fip->name, fop->name);
293         fflush(con_term);
294         set_err_nl(1);
295     }
296     else if (opt_cmd == CMD_TEST && opt_verbose > 0)
297     {
298         /* note: gzip is quiet by default when testing, lzop is not */
299         if (opt_verbose > 2)
300             fprintf(con_term,"testing %s [%s]", fip->name, fop->name);
301         else
302             fprintf(con_term,"testing %s", fip->name);
303         fflush(con_term);
304         set_err_nl(1);
305     }
306 
307     fip->bytes_processed = fop->bytes_processed = 0;
308 
309     switch (h->method)
310     {
311 #if defined(WITH_LZO)
312     case M_LZO1X_1:
313     case M_LZO1X_1_15:
314     case M_LZO1X_999:
315         ok = lzo_decompress(fip,fop,h,skip);
316         break;
317 #endif
318 #if defined(WITH_NRV)
319     case M_NRV1A:
320     case M_NRV1B:
321     case M_NRV2A:
322     case M_NRV2B:
323         ok = nrv_decompress(fip,fop,h,skip);
324         break;
325 #endif
326 #if defined(WITH_ZLIB)
327     case M_ZLIB:
328         ok = zlib_decompress(fip,fop,h,skip);
329         break;
330 #endif
331     default:
332         fatal(fip,"Internal error");
333         ok = 0;
334         break;
335     }
336 
337     if (skip && opt_cmd == CMD_DECOMPRESS && opt_verbose > 0)
338     {
339         fprintf(con_term, ok ? "\n" : " FAILED\n");
340         fflush(con_term);
341     }
342     else if (opt_cmd == CMD_DECOMPRESS && opt_verbose > 1)
343     {
344         fprintf(con_term, ok ? "\n" : " FAILED\n");
345         fflush(con_term);
346     }
347     else if (opt_cmd == CMD_TEST && opt_verbose > 0)
348     {
349         fprintf(con_term, ok ? " OK\n" : " FAILED\n");
350         fflush(con_term);
351     }
352     set_err_nl(0);
353 
354     if (ok && opt_cmd == CMD_TEST)
355         do_test(h,fop->bytes_processed,fip->bytes_processed);
356     if (ok && opt_cmd == CMD_LIST)
357         do_list(h,fop->bytes_processed,fip->bytes_processed);
358     if (ok && opt_cmd == CMD_LS)
359         do_ls(h,fop->bytes_processed,fip->bytes_processed);
360     if (ok && opt_cmd == CMD_INFO)
361         do_info(h,fop->bytes_processed,fip->bytes_processed);
362 
363     x_leave(h);
364     return ok;
365 }
366 
367 
368 /*************************************************************************
369 //
370 **************************************************************************/
371 
x_filter(lzo_bytep p,lzo_uint l,const header_t * h)372 void x_filter(lzo_bytep p, lzo_uint l, const header_t *h)
373 {
374     unsigned f = (unsigned) h->filter;
375     lzo_bool c = (opt_cmd == CMD_COMPRESS);
376 
377     if (f == 0 || l <= 0)
378         return;
379     if (f == 1)
380     {
381         if (c) t_sub1(p,l); else t_add1(p,l);
382     }
383     else if (f <= 16)
384     {
385         if (c) t_sub(p,l,f); else t_add(p,l,f);
386     }
387     else
388     {
389         fatal(NULL,"Invalid filter");
390     }
391 }
392 
393 
394 /* vim:set ts=4 sw=4 et: */
395