rosprite: Cleanup and modernization
[deark.git] / src / fmtutil-lzah.c
blobde5435423bfb2e5bda769c1b6a2f906f4345c320
1 // This file is part of Deark.
2 // Copyright (C) 2021 Jason Summers
3 // See the file COPYING for terms of use.
5 // LZH with adaptive Huffman coding
7 #define DE_NOT_IN_MODULE
8 #include "deark-private.h"
9 #include "deark-fmtutil.h"
11 #include "../foreign/lzhuf.h"
13 void fmtutil_get_lzhuf_d_code_and_len(UI n, UI *pd_code, UI *pd_len)
15 if(n<32 || n>=256) { *pd_code = 0; *pd_len = 3; }
16 else if(n<80) { *pd_code = (n-16)>>4; *pd_len = 4; }
17 else if(n<144) { *pd_code = (n-48)>>3; *pd_len = 5; }
18 else if(n<192) { *pd_code = (n-96)>>2; *pd_len = 6; }
19 else if(n<240) { *pd_code = (n-144)>>1; *pd_len = 7; }
20 else { *pd_code = n-192; *pd_len = 8; };
23 static void my_lh1_codec_addbuf(struct de_dfilter_ctx *dfctx,
24 const u8 *buf, i64 buf_len)
26 struct lzahuf_ctx *cctx = (struct lzahuf_ctx*)dfctx->codec_private;
28 if(dfctx->finished_flag || cctx->errflag) {
29 goto done;
32 lzhuf_Decode_continue(cctx, buf, buf_len, 0);
34 done:
35 if(cctx->errflag) {
36 dfctx->finished_flag = 1;
40 static void my_lh1_codec_finish(struct de_dfilter_ctx *dfctx)
42 struct lzahuf_ctx *cctx = (struct lzahuf_ctx*)dfctx->codec_private;
44 lzhuf_Decode_continue(cctx, NULL, 0, 1);
46 cctx->total_nbytes_processed -= (i64)(cctx->bbll.nbits_in_bitbuf/8);
47 de_bitbuf_lowlevel_empty(&cctx->bbll);
48 dfctx->dres->bytes_consumed = cctx->total_nbytes_processed;
49 dfctx->dres->bytes_consumed_valid = 1;
51 if(cctx->errflag) {
52 de_dfilter_set_generic_error(cctx->c, dfctx->dres, cctx->modname);
56 static void my_lh1_codec_command(struct de_dfilter_ctx *dfctx, int cmd, UI flags)
58 struct lzahuf_ctx *cctx = (struct lzahuf_ctx*)dfctx->codec_private;
60 if(cmd==DE_DFILTER_COMMAND_FINISH_BLOCK) {
61 lzhuf_Decode_continue(cctx, NULL, 0, 1);
62 cctx->total_nbytes_processed -= (i64)(cctx->bbll.nbits_in_bitbuf/8);
63 de_bitbuf_lowlevel_empty(&cctx->bbll);
64 if(cctx->lh1p.is_dms_deep) {
65 de_lz77buffer_set_curpos(cctx->ringbuf, cctx->ringbuf->curpos + 60);
68 else if(cmd==DE_DFILTER_COMMAND_RESET_COUNTERS) {
69 cctx->nbytes_written = 0;
70 cctx->total_nbytes_processed = 0;
71 cctx->errflag = 0;
72 dfctx->finished_flag = 0;
76 static void my_lh1_codec_destroy(struct de_dfilter_ctx *dfctx)
78 struct lzahuf_ctx *cctx = (struct lzahuf_ctx*)dfctx->codec_private;
80 if(cctx) {
81 de_lz77buffer_destroy(cctx->c, cctx->ringbuf);
82 cctx->ringbuf = NULL;
83 de_free(dfctx->c, cctx);
85 dfctx->codec_private = NULL;
88 // codec_private_params: 'struct de_lh1_params'. Can be NULL.
89 void dfilter_lh1_codec(struct de_dfilter_ctx *dfctx, void *codec_private_params)
91 struct lzahuf_ctx *cctx = NULL;
93 cctx = de_malloc(dfctx->c, sizeof(struct lzahuf_ctx));
94 cctx->c = dfctx->c;
95 cctx->modname = "lzhuf";
96 cctx->dfctx = dfctx;
97 cctx->dcmpro = dfctx->dcmpro;
98 cctx->dres = dfctx->dres;
100 dfctx->codec_private = (void*)cctx;
101 dfctx->codec_addbuf_fn = my_lh1_codec_addbuf;
102 dfctx->codec_finish_fn = my_lh1_codec_finish;
103 dfctx->codec_command_fn = my_lh1_codec_command;
104 dfctx->codec_destroy_fn = my_lh1_codec_destroy;
106 if(codec_private_params) {
107 // Use params from caller, if present.
108 de_memcpy(&cctx->lh1p, codec_private_params, sizeof(struct de_lh1_params));
110 else {
111 // Set default params.
112 cctx->lh1p.history_fill_val = 0x20;
115 lzhuf_Decode_init(cctx);
118 // codec_private_params: 'struct de_lh1_params'. Can be NULL.
119 void fmtutil_lh1_codectype1(deark *c, struct de_dfilter_in_params *dcmpri,
120 struct de_dfilter_out_params *dcmpro, struct de_dfilter_results *dres,
121 void *codec_private_params)
123 de_dfilter_decompress_oneshot(c, dfilter_lh1_codec, codec_private_params,
124 dcmpri, dcmpro, dres);