blob: e60affbac405af44a868db397d0d454c122d62bd [file] [log] [blame] [edit]
import 'dart:typed_data';
import '../util/adler32.dart';
import '../util/byte_order.dart';
import '../util/input_stream.dart';
import '../util/input_stream_memory.dart';
import '../util/output_stream.dart';
import '../util/output_stream_memory.dart';
import 'zlib/deflate.dart';
class ZLibEncoder {
static const int _deflate = 8;
const ZLibEncoder();
Uint8List encodeBytes(Uint8List bytes,
{int level = CompressionLevel.defaultCompression}) {
final output = OutputStreamMemory(byteOrder: ByteOrder.bigEndian);
encodeStream(InputStreamMemory(bytes), output, level: level);
return output.getBytes();
}
void encodeStream(InputStream input, OutputStream output,
{int level = CompressionLevel.defaultCompression}) {
output.byteOrder = ByteOrder.bigEndian;
// Compression Method and Flags
const cm = _deflate;
const cinfo = 7; //2^(7+8) = 32768 window size
const cmf = (cinfo << 4) | cm;
output.writeByte(cmf);
// 0x01, (00 0 00001) (FLG)
// bits 0 to 4 FCHECK (check bits for CMF and FLG)
// bit 5 FDICT (preset dictionary)
// bits 6 to 7 FLEVEL (compression level)
// FCHECK is set such that (cmf * 256 + flag) must be a multiple of 31.
const fdict = 0;
const flevel = 0;
var flag = ((flevel & 0x3) << 7) | ((fdict & 0x1) << 5);
var fcheck = 0;
const cmf256 = cmf * 256;
while ((cmf256 + (flag | fcheck)) % 31 != 0) {
fcheck++;
}
flag |= fcheck;
output.writeByte(flag);
final startPos = input.position;
final adler32 = getAdler32Stream(input);
input.setPosition(startPos);
Deflate.stream(input, level: level, output: output)
.deflate();
output..writeUint32(adler32)
..flush();
}
}