📄 compr_lzo.c
字号:
} else do *op++ = *ip++; while (--t > 0); } } else { *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; do *op++ = *ip++; while (--t > 0); } first_literal_run: t = *ip++; if (t >= 16) goto match; m_pos = op - (1 + M2_MAX_OFFSET); m_pos -= t >> 2; m_pos -= *ip++ << 2; TEST_LOOKBEHIND (m_pos, out); NEED_OP (3); *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; goto match_done; while (TEST_IP && TEST_OP) { match: if (t >= 64) { m_pos = op - 1; m_pos -= (t >> 2) & 7; m_pos -= *ip++ << 3; t = (t >> 5) - 1; TEST_LOOKBEHIND (m_pos, out); NEED_OP (t + 3 - 1); goto copy_match; } else if (t >= 32) { t &= 31; if (t == 0) { NEED_IP (1); while (*ip == 0) { t += 255; ip++; NEED_IP (1); } t += 31 + *ip++; } m_pos = op - 1; m_pos -= (ip[0] >> 2) + (ip[1] << 6); ip += 2; } else if (t >= 16) { m_pos = op; m_pos -= (t & 8) << 11; t &= 7; if (t == 0) { NEED_IP (1); while (*ip == 0) { t += 255; ip++; NEED_IP (1); } t += 7 + *ip++; } m_pos -= (ip[0] >> 2) + (ip[1] << 6); ip += 2; if (m_pos == op) goto eof_found; m_pos -= 0x4000; } else { m_pos = op - 1; m_pos -= t >> 2; m_pos -= *ip++ << 2; TEST_LOOKBEHIND (m_pos, out); NEED_OP (2); *op++ = *m_pos++; *op++ = *m_pos; goto match_done; } TEST_LOOKBEHIND (m_pos, out); NEED_OP (t + 3 - 1); if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4 (op, m_pos)) { COPY4 (op, m_pos); op += 4; m_pos += 4; t -= 4 - (3 - 1); do { COPY4 (op, m_pos); op += 4; m_pos += 4; t -= 4; } while (t >= 4); if (t > 0) do *op++ = *m_pos++; while (--t > 0); } else { copy_match: *op++ = *m_pos++; *op++ = *m_pos++; do *op++ = *m_pos++; while (--t > 0); } match_done: t = ip[-2] & 3; if (t == 0) break; match_next: NEED_OP (t); NEED_IP (t + 1); do *op++ = *ip++; while (--t > 0); t = *ip++; } } *out_len = op - out; return LZO_E_EOF_NOT_FOUND; eof_found: *out_len = op - out; return (ip == ip_end ? LZO_E_OK : (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); input_overrun: *out_len = op - out; return LZO_E_INPUT_OVERRUN; output_overrun: *out_len = op - out; return LZO_E_OUTPUT_OVERRUN; lookbehind_overrun: *out_len = op - out; return LZO_E_LOOKBEHIND_OVERRUN;}/* lzo1x_oo.ch */#define NO_LIT LZO_UINT_MAXstatic voidcopy2 (lzo_byte * ip, const lzo_byte * m_pos, lzo_ptrdiff_t off){ ip[0] = m_pos[0]; if (off == 1) ip[1] = m_pos[0]; else ip[1] = m_pos[1];}static voidcopy3 (lzo_byte * ip, const lzo_byte * m_pos, lzo_ptrdiff_t off){ ip[0] = m_pos[0]; if (off == 1) { ip[2] = ip[1] = m_pos[0]; } else if (off == 2) { ip[1] = m_pos[1]; ip[2] = m_pos[0]; } else { ip[1] = m_pos[1]; ip[2] = m_pos[2]; }}static intlzo1x_optimize (lzo_byte * in, lzo_uint in_len, lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem){ register lzo_byte *op; register lzo_byte *ip; register lzo_uint t; register lzo_byte *m_pos; lzo_uint nl; const lzo_byte *const ip_end = in + in_len; const lzo_byte *const op_end = out + *out_len; lzo_byte *litp = NULL; lzo_uint lit = 0; lzo_uint next_lit = NO_LIT; long o_m1_a = 0, o_m1_b = 0, o_m2 = 0, o_m3_a = 0, o_m3_b = 0; *out_len = 0; op = out; ip = in; if (*ip > 17) { t = *ip++ - 17; if (t < 4) goto match_next; goto first_literal_run; } while (TEST_IP && TEST_OP) { t = *ip++; if (t >= 16) goto match; litp = ip - 1; if (t == 0) { t = 15; while (*ip == 0) t += 255, ip++; t += *ip++; } lit = t + 3; copy_literal_run: *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; first_literal_run: do *op++ = *ip++; while (--t > 0); t = *ip++; if (t >= 16) goto match; m_pos = op - 1 - 0x800; m_pos -= t >> 2; m_pos -= *ip++ << 2; *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++; lit = 0; goto match_done; while (TEST_IP && TEST_OP) { if (t < 16) { m_pos = op - 1; m_pos -= t >> 2; m_pos -= *ip++ << 2; if (litp == NULL) goto copy_m1; nl = ip[-2] & 3; if (nl == 0 && lit == 1 && ip[0] >= 16) { next_lit = nl; lit += 2; *litp = LZO_BYTE ((*litp & ~3) | lit); copy2 (ip - 2, m_pos, op - m_pos); o_m1_a++; } else if (nl == 0 && ip[0] < 16 && ip[0] != 0 && (lit + 2 + ip[0] < 16)) { t = *ip++; *litp &= ~3; copy2 (ip - 3 + 1, m_pos, op - m_pos); litp += 2; if (lit > 0) memmove (litp + 1, litp, lit); lit += 2 + t + 3; *litp = LZO_BYTE (lit - 3); o_m1_b++; *op++ = *m_pos++; *op++ = *m_pos++; goto copy_literal_run; } copy_m1: *op++ = *m_pos++; *op++ = *m_pos++; } else { match: if (t >= 64) { m_pos = op - 1; m_pos -= (t >> 2) & 7; m_pos -= *ip++ << 3; t = (t >> 5) - 1; if (litp == NULL) goto copy_m; nl = ip[-2] & 3; if (t == 1 && lit > 3 && nl == 0 && ip[0] < 16 && ip[0] != 0 && (lit + 3 + ip[0] < 16)) { t = *ip++; copy3 (ip - 1 - 2, m_pos, op - m_pos); lit += 3 + t + 3; *litp = LZO_BYTE (lit - 3); o_m2++; *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++; goto copy_literal_run; } } else { if (t >= 32) { t &= 31; if (t == 0) { t = 31; while (*ip == 0) t += 255, ip++; t += *ip++; } m_pos = op - 1; m_pos -= *ip++ >> 2; m_pos -= *ip++ << 6; } else { m_pos = op; m_pos -= (t & 8) << 11; t &= 7; if (t == 0) { t = 7; while (*ip == 0) t += 255, ip++; t += *ip++; } m_pos -= *ip++ >> 2; m_pos -= *ip++ << 6; if (m_pos == op) goto eof_found; m_pos -= 0x4000; } if (litp == NULL) goto copy_m; nl = ip[-2] & 3; if (t == 1 && lit == 0 && nl == 0 && ip[0] >= 16) { next_lit = nl; lit += 3; *litp = LZO_BYTE ((*litp & ~3) | lit); copy3 (ip - 3, m_pos, op - m_pos); o_m3_a++; } else if (t == 1 && lit <= 3 && nl == 0 && ip[0] < 16 && ip[0] != 0 && (lit + 3 + ip[0] < 16)) { t = *ip++; *litp &= ~3; copy3 (ip - 4 + 1, m_pos, op - m_pos); litp += 2; if (lit > 0) memmove (litp + 1, litp, lit); lit += 3 + t + 3; *litp = LZO_BYTE (lit - 3); o_m3_b++; *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++; goto copy_literal_run; } } copy_m: *op++ = *m_pos++; *op++ = *m_pos++; do *op++ = *m_pos++; while (--t > 0); } match_done: if (next_lit == NO_LIT) { t = ip[-2] & 3; lit = t; litp = ip - 2; } else t = next_lit; next_lit = NO_LIT; if (t == 0) break; match_next: do *op++ = *ip++; while (--t > 0); t = *ip++; } } *out_len = op - out; return LZO_E_EOF_NOT_FOUND; eof_found: *out_len = op - out; return (ip == ip_end ? LZO_E_OK : (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));}/* interface to jffs2 follows */#include "compr.h"#include <linux/jffs2.h>/*#define BLOCKSIZE JFFS2_PAGE_SIZE#define OUTBLOCKSIZE (BLOCKSIZE + BLOCKSIZE / 64 + 16 + 3)*/int jffs2_lzo_compress (unsigned char *input, unsigned char *output, uint32_t *sourcelen, uint32_t *dstlen, void *model);int jffs2_lzo_decompress (unsigned char *input, unsigned char *output, uint32_t sourcelen, uint32_t dstlen, void *model);static struct jffs2_compressor jffs2_lzo_comp = { .priority = JFFS2_LZO_PRIORITY, .name = "lzo", .compr = JFFS2_COMPR_LZO, .compress = &jffs2_lzo_compress, .decompress = &jffs2_lzo_decompress,#ifdef JFFS2_LZO_DISABLED .disabled = 1,#else .disabled = 0,#endif};#ifdef JFFS2_LZO_1static intno_lzo1x_optimize (lzo_byte * src, lzo_uint src_len, lzo_byte * dst, lzo_uintp dst_len, lzo_voidp wrkmem){ return 0;}#endifstatic lzo_compress_t lzo1x_compressor = lzo1x_999_compress;static lzo_optimize_t lzo1x_optimizer = lzo1x_optimize;#ifdef JFFS2_LZO_1static int lzo1x_compressor_type = 999;static int lzo1x_optimize_type = 1;#endifstatic unsigned long lzo1x_compressor_memsize = LZO1X_999_MEM_COMPRESS;static lzo_bytep wrkmem = NULL; /* temporary buffer for compression, used by lzo */static lzo_bytep cmprssmem = NULL; /* temporary buffer for compression, used by interface */static int cmprssmem_size = 0;static int prepare_out_buf(uint32_t ssize, uint32_t dsize){ uint32_t msize,req; msize = (ssize>dsize)? ssize : dsize; req = (msize<<1) + 20; if ((!cmprssmem)||(cmprssmem_size<req)) { if (!cmprssmem) { vfree(cmprssmem); cmprssmem = NULL; cmprssmem_size = 0; } cmprssmem = vmalloc(req); if (!cmprssmem) { return -1; } cmprssmem_size = req; } return 0;}int jffs2_lzo_compress (unsigned char *input, unsigned char *output, uint32_t *sourcelen, uint32_t *dstlen, void *model){ lzo_uint csize = *dstlen; /*BLOCKSIZE;*/ lzo_uint isize = *sourcelen; int retval; if (prepare_out_buf(*sourcelen,*dstlen)) { return -1; } if ((retval = lzo1x_compressor (input, *sourcelen, cmprssmem, &csize, wrkmem)) != LZO_E_OK) { return retval; } else { retval = lzo1x_optimizer (cmprssmem, csize, input, &isize, NULL); if (csize <= *dstlen) { *dstlen = csize; memcpy (output, cmprssmem, csize); return retval; } else { return -1; } }}int jffs2_lzo_decompress (unsigned char *input, unsigned char *output, uint32_t sourcelen, uint32_t dstlen, void *model){ lzo_uint outlen = dstlen; return lzo1x_decompress (input, sourcelen, output, &outlen, NULL);}int jffs2_lzo_init (void){ wrkmem = (lzo_bytep) vmalloc(lzo1x_compressor_memsize); if (!wrkmem) return -1; jffs2_register_compressor(&jffs2_lzo_comp); return 0;}void jffs2_lzo_exit (void){ jffs2_unregister_compressor (&jffs2_lzo_comp); if (cmprssmem) vfree(cmprssmem); vfree(wrkmem);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -