public override IntField Decode(Stream input) { // Read size int w = (int)input.ReadUInt32Optim(); int h = (int)input.ReadUInt32Optim(); // Read probabilities ulong[] probs = CodecUtil.LoadFreqsCrappy(input, FieldcodeSymbols + 1); // Read fields ArithmeticSectionsCodec ac = new ArithmeticSectionsCodec(probs, 6); ac.Decode(input); var fields = new List <int[]>(); for (int i = 1; i <= 3; i++) { fields.Add(ac.ReadSection()); } // Undo fieldcode IntField transformed = CodecUtil.FieldcodeRunlengthsDe(fields, w, h, new RunLength01MaxSmartCodec(FieldcodeSymbols), this); // Undo predictive transform transformed.PredictionDeTransformXor(Seer); transformed.ArgbFromField(0, 3); return(transformed); }
public override IntField Decode(Stream input) { // Read size int w = (int)input.ReadUInt32Optim(); int h = (int)input.ReadUInt32Optim(); // Read probabilities ulong[] probs = CodecUtil.LoadFreqs(input, TimwiCecCompressor.runLProbsProbs, RLE.MaxSymbol + 1); // Read fields int len = (int)input.ReadUInt32Optim(); ArithmeticCodingReader acr = new ArithmeticCodingReader(input, probs); int[] fields = new int[len]; for (int p = 0; p < len; p++) { fields[p] = acr.ReadSymbol(); } // Undo fieldcode IntField transformed = CodecUtil.FieldcodeRunlengthsDe2(fields, w, h, RLE, this); // Undo predictive transform transformed.PredictionDeTransformXor(Seer); transformed.ArgbFromField(0, 3); return(transformed); }
public void AddImageGrayscale(IntField image, int min, int max, string caption) { IntField temp = image.Clone(); temp.ArgbFromField(min, max); Images.Add(new Tuple <string, IntField>(caption, temp)); }
public override void Encode(IntField image, Stream output) { image.ArgbTo4c(); image.PredictionEnTransformXor(Seer); IntField[] fields = new IntField[4]; IntField[] cutmaps = new IntField[4]; List <Rectangle>[] areases = new List <Rectangle> [4]; for (int i = 1; i <= 3; i++) { fields[i] = image.Clone(); fields[i].Map(x => x == i ? 1 : 0); cutmaps[i] = fields[i].ReduceKeepingPixels(ReduceBlocksize); areases[i] = new List <Rectangle>(); IntField remains = fields[i].Clone(); while (true) { List <Rectangle> rects = CodecUtil.FindAllRects(cutmaps[i]); if (rects.Count == 0 || rects[0].Width * rects[0].Height <= 1) { break; } Rectangle r = new Rectangle(rects[0].Left * ReduceBlocksize, rects[0].Top * ReduceBlocksize, rects[0].Width * ReduceBlocksize, rects[0].Height * ReduceBlocksize); r = CodecUtil.ShrinkRectangle(remains, r); areases[i].Add(r); cutmaps[i].ShadeRect(rects[0].Left, rects[0].Top, rects[0].Width, rects[0].Height, 0, 0); remains.ShadeRect(r.Left, r.Top, r.Width, r.Height, 0, 0); } SetCounter("areas|" + i, areases[i].Count); IntField vis = fields[i].Clone(); vis.ArgbFromField(0, 1); foreach (var area in areases[i]) { vis.ShadeRect(area.Left, area.Top, area.Width, area.Height, 0xFFFF7F7F, 0x007F0000); } for (int x = 0; x < cutmaps[i].Width; x++) { for (int y = 0; y < cutmaps[i].Height; y++) { if (cutmaps[i][x, y] > 0) { vis.ShadeRect(x * ReduceBlocksize, y * ReduceBlocksize, ReduceBlocksize, ReduceBlocksize, 0xFF7FFF7F, 0x00007F00); } } } AddImageArgb(vis, "vis" + i); } // now have: fields, covered in part by areas and in part by cutmap (only remaining cutmap left at this stage) long pos = 0; output.WriteInt32Optim(image.Width); output.WriteInt32Optim(image.Height); SetCounter("bytes|size", output.Position - pos); pos = output.Position; for (int i = 1; i <= 3; i++) { output.WriteInt32Optim(areases[i].Count); } SetCounter("bytes|areas|count", output.Position - pos); pos = output.Position; for (int i = 1; i <= 3; i++) { foreach (var area in areases[i]) { output.WriteInt32Optim(area.Left); output.WriteInt32Optim(area.Top); } SetCounter("bytes|areas|x,y|" + i, output.Position - pos); pos = output.Position; } for (int i = 1; i <= 3; i++) { foreach (var area in areases[i]) { output.WriteInt32Optim(area.Width); output.WriteInt32Optim(area.Height); } SetCounter("bytes|areas|w,h|" + i, output.Position - pos); pos = output.Position; } for (int i = 1; i <= 3; i++) { var pts = CodecUtil.GetPixelCoords(cutmaps[i], 1); SetCounter("leftpixels|" + i, pts.Count); output.WriteInt32Optim(pts.Count); foreach (var pt in pts) { output.WriteInt32Optim(pt.X); output.WriteInt32Optim(pt.Y); } } RunLength01MaxSmartCodec runlen = new RunLength01MaxSmartCodec(FieldcodeSymbols); List <int> data = new List <int>(); List <int> visdata = new List <int>(); for (int i = 1; i <= 3; i++) { foreach (var area in areases[i]) { int[] aredata = fields[i].GetRectData(area); data.AddRange(aredata); visdata.AddRange(aredata.Select(val => unchecked ((int)0xFF000000) | ((i == 1 ? 0xF00000 : i == 2 ? 0xF08000 : 0xF00080) >> (2 - val * 2)))); fields[i].ShadeRect(area.Left, area.Top, area.Width, area.Height, 0, 0); } } for (int i = 1; i <= 3; i++) { var pts = CodecUtil.GetPixelCoords(cutmaps[i], 1); foreach (var pt in pts) { Rectangle rect = new Rectangle(pt.X * ReduceBlocksize, pt.Y * ReduceBlocksize, ReduceBlocksize, ReduceBlocksize); int[] aredata = fields[i].GetRectData(rect); data.AddRange(aredata); visdata.AddRange(aredata.Select(val => unchecked ((int)0xFF000000) | ((i == 1 ? 0x00F000 : i == 2 ? 0x80F000 : 0x00F080) >> (2 - val * 2)))); } } int[] dataA = data.ToArray(); int[] symbols = runlen.Encode(dataA); SetCounter("crux-pixels", data.Count); SetCounter("crux-rle-symbols", symbols.Length); int viw = (int)(Math.Sqrt(data.Count) * 1.3); int vih = (int)Math.Ceiling((double)data.Count / viw); IntField visual = new IntField(viw, vih); Array.Copy(visdata.ToArray(), visual.Data, visdata.Count); AddImageArgb(visual, "crux"); var probs = CodecUtil.CountValues(symbols); output.WriteUInt32Optim((uint)probs.Length); for (int p = 0; p < probs.Length; p++) { output.WriteUInt64Optim(probs[p]); } SetCounter("bytes|probs", output.Position - pos); pos = output.Position; ArithmeticWriter aw = new ArithmeticWriter(output, probs); foreach (int sym in symbols) { aw.WriteSymbol(sym); } SetCounter("bytes|crux", output.Position - pos); pos = output.Position; aw.Flush(); // BETTER RLE - RUNS OF 1'S // ARITH THE AREAS // ARITH THE PROBS // SHRINK GREENS }