/* compress.c -- This file is part of the lzop file compressor. Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer All Rights Reserved. lzop and the LZO library are free software; you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Markus F.X.J. Oberhumer http://www.oberhumer.com/opensource/lzop/ */ #include "conf.h" /************************************************************************* // **************************************************************************/ int x_set_method(int m, int l) { int r = -1; #if defined(WITH_LZO) r = lzo_set_method(m,l); if (r >= 0) return r; #endif #if defined(WITH_NRV) r = nrv_set_method(m,l); if (r >= 0) return r; #endif #if defined(WITH_ZLIB) r = zlib_set_method(m,l); if (r >= 0) return r; #endif UNUSED(r); return -1; } int x_get_method(header_t *h) { int r = -1; #if defined(WITH_LZO) r = lzo_get_method(h); if (r >= 0) return r; #endif #if defined(WITH_NRV) r = nrv_get_method(h); if (r >= 0) return r; #endif #if defined(WITH_ZLIB) r = zlib_get_method(h); if (r >= 0) return 0; #endif UNUSED(r); return 14; } /************************************************************************* // memory setup **************************************************************************/ lzo_bool x_enter(const header_t *h) { if (h == NULL) { lzo_bool ok = 1; #if defined(WITH_LZO) ok &= lzo_enter(NULL); #endif #if defined(WITH_NRV) ok &= nrv_enter(NULL); #endif #if defined(WITH_ZLIB) ok &= zlib_enter(NULL); #endif return ok; } switch (h->method) { #if defined(WITH_LZO) case M_LZO1X_1: case M_LZO1X_1_15: case M_LZO1X_999: return lzo_enter(h); #endif #if defined(WITH_NRV) case M_NRV1A: case M_NRV1B: case M_NRV2A: case M_NRV2B: return nrv_enter(h); #endif #if defined(WITH_ZLIB) case M_ZLIB: return zlib_enter(h); #endif } return 0; } void x_leave(const header_t *h) { if (h == NULL) { #if defined(WITH_ZLIB) zlib_leave(NULL); #endif #if defined(WITH_NRV) nrv_leave(NULL); #endif #if defined(WITH_LZO) lzo_leave(NULL); #endif return; } switch (h->method) { #if defined(WITH_LZO) case M_LZO1X_1: case M_LZO1X_1_15: case M_LZO1X_999: lzo_leave(h); break; #endif #if defined(WITH_NRV) case M_NRV1A: case M_NRV1B: case M_NRV2A: case M_NRV2B: nrv_leave(h); break; #endif #if defined(WITH_ZLIB) case M_ZLIB: zlib_leave(h); break; #endif } } /************************************************************************* // compress a file **************************************************************************/ lzo_bool x_compress(file_t *fip, file_t *fop, header_t *h) { lzo_bool ok = 0; init_compress_header(h,fip,fop); switch (h->method) { #if defined(WITH_LZO) case M_LZO1X_1: case M_LZO1X_1_15: case M_LZO1X_999: lzo_init_compress_header(h); break; #endif #if defined(WITH_NRV) case M_NRV1A: case M_NRV1B: case M_NRV2A: case M_NRV2B: nrv_init_compress_header(h); break; #endif #if defined(WITH_ZLIB) case M_ZLIB: zlib_init_compress_header(h); break; #endif default: fatal(fip,"Internal error"); break; } if (!x_enter(h)) e_memory(); if (opt_verbose > 1) { if (opt_unlink) fprintf(con_term,"replacing %s with %s", fip->name, fop->name); else fprintf(con_term,"compressing %s into %s", fip->name, fop->name); fflush(con_term); set_err_nl(1); } write_header(fop,h); fip->bytes_processed = fop->bytes_processed = 0; switch (h->method) { #if defined(WITH_LZO) case M_LZO1X_1: case M_LZO1X_1_15: case M_LZO1X_999: ok = lzo_compress(fip,fop,h); break; #endif #if defined(WITH_NRV) case M_NRV1A: case M_NRV1B: case M_NRV2A: case M_NRV2B: ok = nrv_compress(fip,fop,h); break; #endif #if defined(WITH_ZLIB) case M_ZLIB: ok = zlib_compress(fip,fop,h); break; #endif default: fatal(fip,"Internal error"); ok = 0; break; } if (opt_cmd == CMD_COMPRESS && opt_verbose > 1) { fprintf(con_term, ok ? "\n" : " FAILED\n"); fflush(con_term); } set_err_nl(0); x_leave(h); return ok; } /************************************************************************* // decompress a file **************************************************************************/ lzo_bool x_decompress(file_t *fip, file_t *fop, const header_t *h, lzo_bool skip) { lzo_bool ok = 0; if (!x_enter(h)) e_memory(); if (skip) { assert(opt_cmd != CMD_TEST); assert(fop->fd < 0); if (opt_cmd == CMD_DECOMPRESS && opt_verbose > 0) fprintf(con_term,"skipping %s [%s]", fip->name, fop->name); fflush(con_term); set_err_nl(1); } else if (opt_cmd == CMD_DECOMPRESS && opt_verbose > 1) { if (opt_unlink) fprintf(con_term,"restoring %s into %s", fip->name, fop->name); else fprintf(con_term,"decompressing %s into %s", fip->name, fop->name); fflush(con_term); set_err_nl(1); } else if (opt_cmd == CMD_TEST && opt_verbose > 0) { /* note: gzip is quiet by default when testing, lzop is not */ if (opt_verbose > 2) fprintf(con_term,"testing %s [%s]", fip->name, fop->name); else fprintf(con_term,"testing %s", fip->name); fflush(con_term); set_err_nl(1); } fip->bytes_processed = fop->bytes_processed = 0; switch (h->method) { #if defined(WITH_LZO) case M_LZO1X_1: case M_LZO1X_1_15: case M_LZO1X_999: ok = lzo_decompress(fip,fop,h,skip); break; #endif #if defined(WITH_NRV) case M_NRV1A: case M_NRV1B: case M_NRV2A: case M_NRV2B: ok = nrv_decompress(fip,fop,h,skip); break; #endif #if defined(WITH_ZLIB) case M_ZLIB: ok = zlib_decompress(fip,fop,h,skip); break; #endif default: fatal(fip,"Internal error"); ok = 0; break; } if (skip && opt_cmd == CMD_DECOMPRESS && opt_verbose > 0) { fprintf(con_term, ok ? "\n" : " FAILED\n"); fflush(con_term); } else if (opt_cmd == CMD_DECOMPRESS && opt_verbose > 1) { fprintf(con_term, ok ? "\n" : " FAILED\n"); fflush(con_term); } else if (opt_cmd == CMD_TEST && opt_verbose > 0) { fprintf(con_term, ok ? " OK\n" : " FAILED\n"); fflush(con_term); } set_err_nl(0); if (ok && opt_cmd == CMD_TEST) do_test(h,fop->bytes_processed,fip->bytes_processed); if (ok && opt_cmd == CMD_LIST) do_list(h,fop->bytes_processed,fip->bytes_processed); if (ok && opt_cmd == CMD_LS) do_ls(h,fop->bytes_processed,fip->bytes_processed); if (ok && opt_cmd == CMD_INFO) do_info(h,fop->bytes_processed,fip->bytes_processed); x_leave(h); return ok; } /************************************************************************* // **************************************************************************/ void x_filter(lzo_bytep p, lzo_uint l, const header_t *h) { unsigned f = (unsigned) h->filter; lzo_bool c = (opt_cmd == CMD_COMPRESS); if (f == 0 || l <= 0) return; if (f == 1) { if (c) t_sub1(p,l); else t_add1(p,l); } else if (f <= 16) { if (c) t_sub(p,l,f); else t_add(p,l,f); } else { fatal(NULL,"Invalid filter"); } } /* vim:set ts=4 sw=4 et: */