vcrle.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach/***********************************************************************
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy Gimblett* *
e071fb22ea9923a2a4ff41184d80ca46b55ee932Till Mossakowski* This software is part of the ast package *
e85b224577b78d08ba5c39fe9dcc2e53995454a2Christian Maeder* Copyright (c) 2003-2011 AT&T Intellectual Property *
97018cf5fa25b494adffd7e9b4e87320dae6bf47Christian Maeder* and is licensed under the *
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach* Eclipse Public License, Version 1.0 *
b4fbc96e05117839ca409f5f20f97b3ac872d1edTill Mossakowski* by AT&T Intellectual Property *
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach* *
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach* A copy of the License is available at *
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach* http://www.eclipse.org/org/documents/epl-v10.html *
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach* *
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach* Information and Software Systems Research *
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach* AT&T Research *
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach* Florham Park NJ *
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach* *
90047eafd2de482c67bcd13103c6064e9b0cb254Andy Gimblett* Phong Vo <kpv@research.att.com> *
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimblett* *
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett***********************************************************************/
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett#include <vclib.h>
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimblett
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett/* Various run-length-encoding methods.
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach**
1538a6e8d77301d6de757616ffc69ee61f1482e4Andy Gimblett** Written by Kiem-Phong Vo (kpv@research.att.com)
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach*/
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimbletttypedef struct _rle_s Rle_t;
8528886a04f14abe0ddf80f50c853cc25bc821cdAndy Gimbletttypedef ssize_t (*Rle_f)_ARG_((Rle_t*, int));
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbachstatic ssize_t rle0 _ARG_((Rle_t*, int));
792df0347edab377785d98c63e2be8e2ce0a8bdeChristian Maederstatic ssize_t rle1 _ARG_((Rle_t*, int));
0ea916d1e6aea10fd7b84f802fb5148a79d8c20aAndy Gimblettstatic ssize_t rle2 _ARG_((Rle_t*, int));
04ceed96d1528b939f2e592d0656290d81d1c045Andy Gimblettstatic ssize_t rleg _ARG_((Rle_t*, int));
d9e78002fb0bf01a9b72d3d3415fdf9790bdfee8Andy Gimblett
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimblettstruct _rle_s
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett{
1538a6e8d77301d6de757616ffc69ee61f1482e4Andy Gimblett Rle_f rlef; /* rle function to call */
c4b2418421546a337f83332fe0db04742dcd735dAndy Gimblett Vcchar_t* ibuf; /* default input data */
41486a487c9b065d4d9d1a8adf63c00925cd455bAndy Gimblett ssize_t isiz;
41486a487c9b065d4d9d1a8adf63c00925cd455bAndy Gimblett
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett Vcchar_t* obuf; /* default output data */
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett ssize_t osiz;
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett Vcchar_t* endo; /* upper bound of array */
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett Vcchar_t* abuf; /* auxiliary buffer */
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett ssize_t asiz;
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblett
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblett Vcchar_t run1; /* run-heads of rle2() */
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblett Vcchar_t run2;
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblett};
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblett
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett/* arguments to select type of run length coder */
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblettstatic Vcmtarg_t _Rleargs[] =
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett{ { "0", "Run-length-encoding: 0-sequences only.", (Void_t*)rle0 },
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett { "1", "Run-length-encoding: 0&1-sequences only.", (Void_t*)rle1 },
41486a487c9b065d4d9d1a8adf63c00925cd455bAndy Gimblett { "2", "Run-length-encoding: Alphabet has only two letters.", (Void_t*)rle2 },
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett { 0 , "General run-length-encoding.", (Void_t*)rleg }
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett};
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimblett
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimblett/* Encoding 0-run's only. Useful for sequences undergone entropy reduction
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett transforms such as Burrows-Wheele + MTF or the column prediction method.
61051521e4d82769a47f23aecb5fb477de47d534Andy Gimblett*/
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimblett#if __STD_C
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimblettstatic ssize_t rle0(Rle_t* rle, int encoding)
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimblett#else
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblettstatic ssize_t rle0(rle, encoding)
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy GimblettRle_t* rle;
d9e78002fb0bf01a9b72d3d3415fdf9790bdfee8Andy Gimblettint encoding;
eeaf0a8a1dc535d105904a2190f26c0835ecf429Andy Gimblett#endif
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett{
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett ssize_t c, z;
e8c03c10d7987b223a9f6bfd5c0c54da21da5b86Andy Gimblett Vcchar_t *dt, *enddt, *o, *endo;
fbc0c2baf563fe5b664f0152674a8d3acecca58cAndy Gimblett Vcio_t io;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett enddt = (dt = rle->ibuf) + rle->isiz;
e771539425f4a0abef9f94cf4b63690f3603f682Andy Gimblett o = rle->obuf; rle->osiz = 0;
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett if(encoding)
820947bd01ca952c3909eaa0366c6914c87cc1cbTill Mossakowski { for(z = -1; dt < enddt; ++dt)
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett { if((c = *dt) == 0)
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett z += 1;
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett else
fbc0c2baf563fe5b664f0152674a8d3acecca58cAndy Gimblett { if(z >= 0) /* encode the 0-run */
90047eafd2de482c67bcd13103c6064e9b0cb254Andy Gimblett { /**/DEBUG_PRINT(9,"%d\n",z);
e8c03c10d7987b223a9f6bfd5c0c54da21da5b86Andy Gimblett vcioinit(&io, o, 8*sizeof(ssize_t));
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett vcioput2(&io, z, 0, RL_ZERO);
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett o = vcionext(&io);
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett z = -1;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett }
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett if(c >= RL_ZERO) /* literal encoding */
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett *o++ = RL_ESC;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett *o++ = c;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett }
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett }
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett if(z >= 0) /* final 0-run if any */
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett { /**/DEBUG_PRINT(9,"%d\n",z);
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett vcioinit(&io, o, 8*sizeof(ssize_t));
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett vcioput2(&io, z, 0, RL_ZERO);
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett o = vcionext(&io);
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett }
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett }
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett else
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett { for(endo = rle->endo; dt < enddt; )
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett { if((c = *dt++) == RL_ESC)
a79fe3aad8743ea57e473ea5f66a723244cb9c0eMarkus Roggenbach { if(dt >= enddt) /* premature EOF */
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblett return -1;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett c = *dt++;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett if(o >= endo || c < RL_ZERO) /* corrupted data */
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett return -1;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett *o++ = c;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett }
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett else if(c == 0 || c == RL_ZERO)
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett { vcioinit(&io, dt-1, (enddt-dt)+1);
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett z = vcioget2(&io, 0, RL_ZERO); /**/DEBUG_PRINT(9,"%d\n",z);
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblett dt = vcionext(&io);
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett if(o+z > endo)
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett return -1;
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett for(; z >= 0; --z)
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett *o++ = 0;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett }
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett else
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett { if(o >= endo)
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett return -1;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett *o++ = c;
8528886a04f14abe0ddf80f50c853cc25bc821cdAndy Gimblett }
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett }
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett }
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett return (rle->osiz = o - rle->obuf);
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett}
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett/* Like rle0() but including 1-run's as well as 0-runs */
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett#if __STD_C
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblettstatic ssize_t rle1(Rle_t* rle, int encoding)
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett#else
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblettstatic ssize_t rle1(rle, encoding)
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy GimblettRle_t* rle;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblettint encoding;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett#endif
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblett{
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett ssize_t c, rc, rz;
e8c03c10d7987b223a9f6bfd5c0c54da21da5b86Andy Gimblett Vcchar_t *dt, *enddt, *o, *endo;
e8c03c10d7987b223a9f6bfd5c0c54da21da5b86Andy Gimblett Vcio_t io;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett
e8c03c10d7987b223a9f6bfd5c0c54da21da5b86Andy Gimblett enddt = (dt = rle->ibuf) + rle->isiz;
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett o = rle->obuf; rle->osiz = 0;
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett if(encoding)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett { for(rc = rz = -1; dt < enddt; ++dt)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett { if((c = *dt) == 0 || c == 1)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett { if(c == rc)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett rz += 1;
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett else
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett { if(rz >= 0)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett { vcioinit(&io, o, 8*sizeof(ssize_t));
e8c03c10d7987b223a9f6bfd5c0c54da21da5b86Andy Gimblett if(rc == 0)
e8c03c10d7987b223a9f6bfd5c0c54da21da5b86Andy Gimblett vcioput2(&io, rz, 0, RL_ZERO);
7caf9f99d426a25d56eb7473fea1f55ce4460762Andy Gimblett else vcioput2(&io, rz, 1, RL_ONE);
d326dac41dadbe2b84bb7021cbfd91f4dd4a19bcAndy Gimblett o = vcionext(&io);
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett }
e8c03c10d7987b223a9f6bfd5c0c54da21da5b86Andy Gimblett
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett rc = c; rz = 0;
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett }
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett }
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett else
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett { if(rz >= 0) /* encode the 0/1-run */
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett { vcioinit(&io, o, 8*sizeof(ssize_t));
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett if(rc == 0)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett vcioput2(&io, rz, 0, RL_ZERO);
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett else vcioput2(&io, rz, 1, RL_ONE);
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett o = vcionext(&io);
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett rc = rz = -1;
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett }
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett
e95030058b77cb83593c85aa4c506caf154f63b7Andy Gimblett if(c >= RL_ONE) /* literal encoding */
e8c03c10d7987b223a9f6bfd5c0c54da21da5b86Andy Gimblett *o++ = RL_ESC;
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett *o++ = c;
fbc0c2baf563fe5b664f0152674a8d3acecca58cAndy Gimblett }
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett }
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett if(rz >= 0) /* final 0/1-run if any */
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett { vcioinit(&io, o, 8*sizeof(ssize_t));
d9e78002fb0bf01a9b72d3d3415fdf9790bdfee8Andy Gimblett if(rc == 0)
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett vcioput2(&io, rz, 0, RL_ZERO);
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett else vcioput2(&io, rz, 1, RL_ONE);
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett o = vcionext(&io);
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett }
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett }
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett else
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett { for(endo = rle->endo; dt < enddt; )
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett { if((c = *dt++) == RL_ESC)
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett { if(dt >= enddt) /* premature EOF */
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett return -1;
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett c = *dt++;
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett if(o >= endo || c < RL_ONE) /* corrupted data */
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett return -1;
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett *o++ = c;
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett }
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett else if(c == 0 || c == RL_ZERO || c == 1 || c == RL_ONE)
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett { vcioinit(&io, dt-1, (enddt-dt)+1);
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett if(c == 0 || c == RL_ZERO)
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett rz = vcioget2(&io, 0, RL_ZERO);
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett else rz = vcioget2(&io, 1, RL_ONE);
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett dt = vcionext(&io);
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett if(o+rz > endo)
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett return -1;
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett if(c == 0 || c == RL_ZERO)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett { for(; rz >= 0; --rz)
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett *o++ = 0;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett }
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett else
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett { for(; rz >= 0; --rz)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett *o++ = 1;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett }
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett }
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett else
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett { if(o >= endo)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett return -1;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett *o++ = c;
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett }
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett }
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett }
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett return (rle->osiz = o - rle->obuf);
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett}
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett/* Encoding a sequence with at most two distinct letters */
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett#if __STD_C
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblettstatic ssize_t rle2(Rle_t* rle, int encoding)
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett#else
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblettstatic ssize_t rle2(rle, encoding)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy GimblettRle_t* rle;
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblettint encoding;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett#endif
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett{
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett Vcchar_t *dt, *enddt;
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett ssize_t sz, n, k, c, c1, c2;
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett Vcio_t io;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett if(encoding)
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett { dt = rle->ibuf; sz = rle->isiz; /**/DEBUG_ASSERT(sz >= 1);
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett vcioinit(&io, rle->obuf, rle->osiz);
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett for(c1 = dt[0], n = 1; n < sz; ++n)
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett if(dt[n] != c1)
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett break;
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett if(n == sz)
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett c2 = c1; /* just a single run */
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett else
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett { c2 = dt[n];
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett for(c = c1, k = n; k < sz; ++k)
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett { if(dt[k] == c) /* current run continues */
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett n += 1;
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett else /* end of current run */
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett { if((c = dt[k]) != c1 && c != c2)
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett RETURN(-1);
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett vcioputu(&io, n-1);
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett n = 1;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett }
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett }
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett }
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett vcioputu(&io, n-1); /* output length of last run */
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett rle->run1 = c1; rle->run2 = c2;
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett return rle->osiz = vciosize(&io);
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett }
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett else
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett { dt = rle->obuf; enddt = rle->endo;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett c1 = rle->run1; c2 = rle->run2;
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett vcioinit(&io, rle->ibuf, rle->isiz);
06dd4e7c29f33f6122a910719e3bd9062256e397Andy Gimblett for(c = c1; vciomore(&io) > 0;)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett { for(n = vciogetu(&io); n >= 0 && dt < enddt; --n, ++dt)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett *dt = c;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett c = c == c1 ? c2 : c1; /* alternate run letters */
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett }
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett if(vciomore(&io) != 0)
fbc0c2baf563fe5b664f0152674a8d3acecca58cAndy Gimblett RETURN(-1);
fbc0c2baf563fe5b664f0152674a8d3acecca58cAndy Gimblett
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett return (rle->osiz = dt - rle->obuf);
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett }
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett}
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett/* General rl-encoding using escape codes */
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett#if __STD_C
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblettstatic ssize_t rleg(Rle_t* rle, int encoding)
d9e78002fb0bf01a9b72d3d3415fdf9790bdfee8Andy Gimblett#else
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblettstatic ssize_t rleg(rle, encoding)
9582375827616730f146b77f9d5a4fd0cc78bc47Andy GimblettRle_t* rle;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblettint encoding;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett#endif
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett{
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett Vcchar_t c, *chr, *run, *dt, *enddt, *endb, *nextb;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett ssize_t r;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett Vcio_t io;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett if(encoding)
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett { endb = (dt = rle->ibuf) + rle->isiz;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett /* set buffers for runs and data */
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett chr = rle->obuf;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett run = rle->abuf;
fbc0c2baf563fe5b664f0152674a8d3acecca58cAndy Gimblett for(; dt < endb; dt = nextb)
fbc0c2baf563fe5b664f0152674a8d3acecca58cAndy Gimblett { for(c = *dt, nextb = dt+1; nextb < endb; ++nextb)
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett if(*nextb != c)
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett break;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett if((r = nextb-dt) >= 3 || c == RL_ESC)
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett { /* in-line small cases here for speed */
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett if(r < (1<<7))
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett *run++ = r;
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett else if(r < (1<<14))
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett { *run++ = (r>>7)|128;
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett *run++ = r&127;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett }
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett else
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett { vcioinit(&io, run, 2*sizeof(ssize_t));
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett vcioputu(&io, r);
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett run = vcionext(&io);
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett }
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett *chr++ = RL_ESC;
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett if(c != RL_ESC || r > 1)
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett *chr++ = c;
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett }
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett else
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett { *chr++ = c;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett if(r == 2)
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett *chr++ = c;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett }
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett }
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett return (rle->osiz = chr - rle->obuf) + (rle->asiz = run - rle->abuf);
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett }
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett else
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett { dt = rle->obuf; enddt = rle->endo;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett vcioinit(&io, rle->abuf, rle->asiz);
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett for(endb = (chr = rle->ibuf) + rle->isiz; chr < endb; )
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett { if((c = *chr++) != RL_ESC)
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett { if(dt >= enddt)
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett return -1;
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett *dt++ = c;
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett }
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett else
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett { r = vciogetu(&io);
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett if(dt+r > enddt)
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett return -1;
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett if(r == 1)
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett *dt++ = RL_ESC;
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett else for(c = *chr++; r > 0; --r)
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett *dt++ = c;
a731366827a80af216ce6bfd4aa6388260577791Andy Gimblett }
31f039ffdb33d78cb31d24b71d3155b11a323975Andy Gimblett }
d297a45fc73aa6c4a1f9d073c3170611415f324bAndy Gimblett
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett return (rle->osiz = dt - rle->obuf);
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett }
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett}
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett#if __STD_C
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblettstatic ssize_t vcrle(Vcodex_t* vc, const Void_t* data, size_t size, Void_t** out)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett#else
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblettstatic ssize_t vcrle(vc, data, size, out)
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy GimblettVcodex_t* vc;
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy GimblettVoid_t* data;
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblettsize_t size;
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy GimblettVoid_t** out;
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett#endif
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett{
f18cf8a4e7d512a2f57365ab1e9e7fdbb98ba257Andy Gimblett Vcchar_t *dt, *output, *space;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett ssize_t k, hd, sz, outsz;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett Vcio_t io;
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett Rle_t *rle = vcgetmtdata(vc, Rle_t*);
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett
9582375827616730f146b77f9d5a4fd0cc78bc47Andy Gimblett if(size == 0)
return 0;
/* input data to encode */
rle->ibuf = (Vcchar_t*)data;
rle->isiz = (ssize_t)size;
/* size of header in transformed data */
hd = vcsizeu(size);
if(rle->rlef == rle2)
hd += 2; /* for the two run bytes */
/* allocate buffers for transformed data */
if(rle->rlef == rleg) /* size for data + size/2 for lengths */
outsz = 2*vcsizeu(size) + size + size/2;
else if(rle->rlef == rle2)
outsz = size; /* binary coding never exceeds size */
else if(size < 64*1024*1024) /* if get here: rle0/1 coding */
outsz = 2*size; /* small, just overallocate */
else /* count the extra RL_ESC's that might be needed */
{ for(dt = rle->ibuf, sz = 0, k = 0; k < size; ++k)
if(dt[k] >= RL_ONE)
sz += 1;
outsz = size + sz;
}
if(!(output = space = vcbuffer(vc, NIL(Vcchar_t*), outsz+128, hd)) )
RETURN(-1);
if(rle->rlef == rleg)
{ rle->obuf = output + vcsizeu(size);
rle->endo = rle->obuf + (rle->osiz = size);
rle->abuf = rle->endo + vcsizeu(size);
rle->asiz = size/2;
if((sz = (*rle->rlef)(rle, 1)) < 0 )
RETURN(-1);
if(vc->coder) /* run continuator on the two parts */
{ if(vcrecode(vc, &rle->obuf, &rle->osiz, 0, 0) < 0)
RETURN(-1);
if(vcrecode(vc, &rle->abuf, &rle->asiz, 0, 0) < 0)
RETURN(-1);
}
sz = vcsizeu(rle->osiz) + rle->osiz + vcsizeu(rle->asiz) + rle->asiz;
if(sz > outsz)
output = vcbuffer(vc, NIL(Vcchar_t*), sz, hd);
vcioinit(&io, output, sz);
vcioputu(&io, rle->osiz);
if(rle->obuf != vcionext(&io))
vcioputs(&io, rle->obuf, rle->osiz);
else vcioskip(&io, rle->osiz);
vcioputu(&io, rle->asiz);
if(rle->abuf != vcionext(&io))
vcioputs(&io, rle->abuf, rle->asiz);
else vcioskip(&io, rle->asiz);
sz = vciosize(&io);
}
else
{ rle->obuf = output;
rle->endo = rle->obuf + outsz;
if((sz = (*rle->rlef)(rle, 1)) < 0 )
RETURN(-1);
if(vcrecode(vc, &output, &sz, hd, 0) < 0 )
RETURN(-1);
}
if(space != output) /* free space if unused */
vcbuffer(vc, space, -1, -1);
output -= hd; sz += hd;
vcioinit(&io, output, hd);
vcioputu(&io, size);
if(rle->rlef == rle2)
{ vcioputc(&io, rle->run1);
vcioputc(&io, rle->run2);
}
if(!(output = vcbuffer(vc, output, sz, -1)) ) /* truncate buffer to size */
RETURN(-1);
if(out)
*out = output;
return sz;
}
#if __STD_C
static ssize_t vcunrle(Vcodex_t* vc, const Void_t* data, size_t size, Void_t** out)
#else
static ssize_t vcunrle(vc, data, size, out)
Vcodex_t* vc;
Void_t* data;
size_t size;
Void_t** out;
#endif
{
Vcchar_t *output;
ssize_t sz;
Vcio_t io;
Rle_t *rle = vcgetmtdata(vc, Rle_t*);
if(size == 0)
return 0;
rle->ibuf = rle->abuf = NIL(Vcchar_t*);
rle->isiz = rle->asiz = 0;
vcioinit(&io, data, size);
if((sz = vciogetu(&io)) <= 0 )
RETURN(-1);
if(rle->rlef == rle2) /* get the two run bytes */
{ if(vciomore(&io) < 2)
RETURN(-1);
rle->run1 = vciogetc(&io);
rle->run2 = vciogetc(&io);
}
if(!(output = vcbuffer(vc, (Vcchar_t*)0, sz, 0)) )
RETURN(-1);
rle->obuf = output;
rle->endo = rle->obuf + sz;
if(rle->rlef == rleg)
{ if(vciomore(&io) <= 0 || (rle->isiz = vciogetu(&io)) < 0)
RETURN(-1);
if(vciomore(&io) < rle->isiz)
RETURN(-1);
rle->ibuf = vcionext(&io);
vcioskip(&io, rle->isiz);
if(vciomore(&io) <= 0 || (rle->asiz = vciogetu(&io)) < 0)
RETURN(-1);
if(vciomore(&io) < rle->asiz)
RETURN(-1);
rle->abuf = vcionext(&io);
/* decode data by secondary encoders */
if(vcrecode(vc, &rle->ibuf, &rle->isiz, 0, 0) < 0)
RETURN(-1);
if(vcrecode(vc, &rle->abuf, &rle->asiz, 0, 0) < 0)
RETURN(-1);
}
else
{ if(vciomore(&io) <= 0 || (rle->isiz = vciomore(&io)) < 0 )
RETURN(-1);
rle->ibuf = vcionext(&io);
if(vcrecode(vc, &rle->ibuf, &rle->isiz, 0, 0) < 0)
RETURN(-1);
}
if((*rle->rlef)(rle, 0) != sz) /* decode run data */
RETURN(-1);
/* free temporary data */
if(rle->ibuf && (rle->ibuf < (Vcchar_t*)data || rle->ibuf >= (Vcchar_t*)data+size) )
vcbuffer(vc, rle->ibuf, -1, -1);
if(rle->abuf && (rle->abuf < (Vcchar_t*)data || rle->abuf >= (Vcchar_t*)data+size) )
vcbuffer(vc, rle->abuf, -1, -1);
if(out)
*out = output;
return sz;
}
#if __STD_C
static ssize_t rleextract(Vcodex_t* vc, Vcchar_t** datap)
#else
static ssize_t rleextract(vc, datap)
Vcodex_t* vc;
Vcchar_t** datap; /* basis string for persistence */
#endif
{
Vcmtarg_t *arg;
char *ident;
ssize_t n;
Rle_t *rle = vcgetmtdata(vc, Rle_t*);
for(arg = _Rleargs;; ++arg)
if(!arg->name || arg->data == (Void_t*)rle->rlef)
break;
if(!arg->name)
return 0;
n = strlen(arg->name);
if(!(ident = (char*)vcbuffer(vc, NIL(Vcchar_t*), sizeof(int)*n+1, 0)) )
RETURN(-1);
if(!(ident = vcstrcode(arg->name, ident, sizeof(int)*n+1)) )
RETURN(-1);
if(datap)
*datap = (Void_t*)ident;
return n;
}
#if __STD_C
static Vcodex_t* rlerestore(Vcchar_t* data, ssize_t dtsz)
#else
static Vcodex_t* rlerestore(data, dtsz)
Vcchar_t* data; /* persistence data */
ssize_t dtsz;
#endif
{
Vcmtarg_t *arg;
char *ident, buf[1024];
for(arg = _Rleargs; arg->name; ++arg)
{ if(!(ident = vcstrcode(arg->name, buf, sizeof(buf))) )
return NIL(Vcodex_t*);
if(dtsz == strlen(ident) && strncmp(ident, (Void_t*)data, dtsz) == 0)
break;
}
return vcopen(0, Vcrle, (Void_t*)arg->name, 0, VC_DECODE);
}
#if __STD_C
static int rleevent(Vcodex_t* vc, int type, Void_t* params)
#else
static int rleevent(vc, type, params)
Vcodex_t* vc;
int type;
Void_t* params;
#endif
{
Rle_t *rle;
Vcmtarg_t *arg;
Vcmtcode_t *mtcd;
char *data;
if(type == VC_OPENING )
{ for(arg = NIL(Vcmtarg_t*), data = (char*)params; data && *data; )
{ data = vcgetmtarg(data, 0, 0, _Rleargs, &arg);
if(arg && arg->name)
break;
}
if(!arg)
for(arg = _Rleargs;; ++arg)
if(!arg->name)
break;
if(!(rle = (Rle_t*)calloc(1,sizeof(Rle_t))) )
RETURN(-1);
rle->rlef = (Rle_f)arg->data;
vcsetmtdata(vc, rle);
return 0;
}
else if(type == VC_CLOSING)
{ if((rle = vcgetmtdata(vc, Rle_t*)) )
free(rle);
return 0;
}
else if(type == VC_EXTRACT)
{ if(!(mtcd = (Vcmtcode_t*)params) )
RETURN(-1);
if((mtcd->size = rleextract(vc, &mtcd->data)) < 0 )
RETURN(-1);
return 1;
}
else if(type == VC_RESTORE)
{ if(!(mtcd = (Vcmtcode_t*)params) )
RETURN(-1);
if(!(mtcd->coder = rlerestore(mtcd->data, mtcd->size)) )
RETURN(-1);
return 1;
}
return 0;
}
Vcmethod_t _Vcrle =
{ vcrle,
vcunrle,
rleevent,
"rle", "Run-length encoding.",
"[-version?rle (AT&T Research) 2003-01-01]" USAGE_LICENSE,
_Rleargs,
1024*1024,
0
};
VCLIB(Vcrle)