void bw1_DoWork(object sender, DoWorkEventArgs e) { Compressor compressor = new Compressor(); Console.WriteLine("Compressing red channel"); _redChannelData = compressor.Compress(_redChannel); Console.WriteLine("Red channel compressed"); s.Release(); }
public byte[,] Decompress(ChannelData cd) { int _delta; int _Delta; int _dMax; Queue <Point> _IP; Queue <Region> _regions; int width, height; width = cd.Width; height = cd.Height; _dMax = cd.DMax; _delta = cd.SmallDelta; _Delta = cd.BigDelta; //_CON = (List<double>)formatter.Deserialize(inputStream); _IP = new Queue <Point>(cd.InterpolationPoints); //_AD = (List<Address>)formatter.Deserialize(inputStream); _regions = new Queue <Region>(cd.Regions); byte[,] image = new byte[width, height]; foreach (Point interpolationPoint in _IP) { image[interpolationPoint.X, interpolationPoint.Y] = (byte)interpolationPoint.Z; } double a = (double)_delta / (double)_Delta; double logdelta = Math.Log(_delta); double logA = Math.Log(a); int steps = (int)Math.Truncate(logdelta / logA); steps = Math.Abs(steps); //posortowaæ kolejkê for (int step = 1; step <= steps; step++) { foreach (Region r in _regions) { correctRegion(r, _delta); if (r.Depth > step) { continue; } //Params parameters = r.Parameters; //Domain domain = r.Domain; Domain domain = Domain.fromIndex(r.DomainIdx, _Delta, width, height); double factor = r.ContractivityFactor; int krok = (int)((double)_delta / (Math.Pow(a, -(step - 1)))); Map(krok, domain, r, image); } } return(image); }
private void ChannelDataViewer_Paint(object sender, PaintEventArgs e) { ChannelData cd = null; Pen pen = Pens.Black; if (state == 0) { cd = red; pen = Pens.Red; } else if (state == 1) { cd = green; pen = Pens.Green; } else { cd = blue; pen = Pens.Blue; } if (cd == null) { return; } Graphics g = e.Graphics; int xDomains = (cd.Width - 1) / cd.BigDelta; int yHeight = (cd.Height - 1) / cd.BigDelta; for (int x = 0; x < xDomains; x++) { for (int y = 0; y < yHeight; y++) { g.DrawRectangle(Pens.Black, x * cd.BigDelta, y * cd.BigDelta, cd.BigDelta + 2, cd.BigDelta + 2); } } foreach (Region r in cd.Regions) { g.DrawRectangle(pen, r.Left, r.Bottom, r.Width + 1, r.Height + 1); } }
private void loadCompressedDataToolStripMenuItem_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() != DialogResult.OK) { return; } FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open); GZipStream zip = new GZipStream(fs, CompressionMode.Decompress, true); MemoryStream ms = new MemoryStream(); byte[] buffer = new byte[(int)Math.Pow(2, 16)]; int bytesRead; bool continueLoop = true; while (continueLoop) { bytesRead = zip.Read(buffer, 0, buffer.Length); if (bytesRead == 0) { break; } ms.Write(buffer, 0, bytesRead); } zip.Close(); fs.Close(); ms.Position = 0; BinaryReader br = new BinaryReader(ms); fc.RedChannel = ChannelData.deserialize(br); fc.GreenChannel = ChannelData.deserialize(br); fc.BlueChannel = ChannelData.deserialize(br); br.Close(); MessageBox.Show("Data loaded"); }
/// <summary> /// Kompresja jednej skladowej koloru. /// </summary> /// <param name="bitmap">tablica z wartosciami skladowej koloru</param> /// <param name="outputStream">strumien do ktorego zostanie zapisane wszystko</param> public ChannelData Compress(byte[,] bitmap) { /* * realizacja algorytmu ze strony 6. */ this.bitmap = bitmap; int width = bitmap.GetLength(0); int height = bitmap.GetLength(1); #region Step 2) /* * punkt 2. create two queues, one named 'squeue' and put all the regions inside as well * as a queue named 'iqueue' and put all initial interpolation points inside. * In addition create two empty queues named 'cqueue' and 'aqueue' (we store contractivity factors in * the first and the addresses in the latter). set the depth d = 1 and create queue named 'squeue2'. */ Console.WriteLine("Generowanie regionów"); LinkedList <Region> regionsToProcess = Region.GenerateRegions(Settings.Default.SmallDelta, width, height); Console.WriteLine("Generowanie punktów interpolacji"); Queue <Point> interpolationPoints = GenerateInterpolationPoints(width, height); Console.WriteLine("Inicjowanie kolejek i tablicy regionów"); Region[,] regionsMap = new Region[width, height]; Queue <Region> regionsProcessed = new Queue <Region>(); foreach (Region reg in regionsToProcess) { regionsMap[reg.Left, reg.Bottom] = reg; } Console.WriteLine("Generowanie domen"); Queue <Domain> domains = Domain.GenerateDomains(Settings.Default.BigDelta, width, height); #endregion Console.WriteLine("Start kompresji"); #region Step 3) /* * Punkt 3. * while 'squeue' is not empty do: */ while (regionsToProcess.Count != 0) { /* * 3.a: * get one region from squeue */ Region region = regionsToProcess.First.Value; regionsToProcess.RemoveFirst(); double minHij = Double.MaxValue; Params minParams = null; Domain minDomain = null; double minContrFactor = Double.MaxValue; bool passedContractivity = false; bool passedContinuity = false; //bool firstRun = true; bool alreadyFoundMatching = false; foreach (Domain domain in domains) { /* * 3.b.x. * compute the contractivity factor for the map acciociated with the y-th domain and the region. */ double contractivityFactor = ComputeContractivityFactor(domain, region); /* * 3.b.ii. * if |s| >= 1 go to 3.b.v . otherwise chec the condition of continuity. if it doesn't hold, go to 3.b.v */ if (Math.Abs(contractivityFactor) < 1) { passedContractivity = true; } else if (alreadyFoundMatching) { continue; } region.ContractivityFactor = contractivityFactor; if (CheckConditionOfContinuity(domain, region, regionsMap, Settings.Default.SmallDelta) == true) { passedContinuity = true; } else if (alreadyFoundMatching) { continue; } /* * 3.b.iii. * Compute the other parameters and map the points of the y-th domain (say Dj) through 'w' according * to the 'mapping algorithm'. say w(Dj) the emerging set. */ /* * The Mapping Algorithm: We map the domain Dj to the region R. * * MA:1. Put the endpoints of the region R to the new set w(Dj) * * MA:2. Compute the other parameters. Let a = delta/Delta, where delta,Delta are the side of the region * and the corresponding domain, respectively. */ Params parameters; if (Common.TryMapDomainToRegion(domain, region, contractivityFactor, bitmap, out parameters)) { minParams = parameters; } else { throw new Exception("moja glowa!! brak rozwiazania"); } /* * MA:3. Map the points of the first and last row (of Dj) as follows. The first and the last point of these * rows of Dj are interpolation points and the have been already mapped. Map the (a+1)-th point of the domain * to the 2nd point of the w(Dj). Continue by mapping the (2a +1), (3a + 1),.. point of the domain to the * 3rd,rth ... point of the w(Dj) * * MA:4. For all other rows: Map the (a+1),(2a+1),.. point of the domain to the 1st,2nd.. point of w(Dj) * * to wszystko bedzie potrzebne do wyliczenia odleglosci hij. gdzies trzeba zapamietac te punkty. */ /* * 3.b.iv. * compute (with a proper distance measure) the distance hij between w(Dj) and the points of region x. */ double hij = Distance(domain, region, parameters); /* * trzeba wszystko to zapamietac jesli hij jest mniejsze */ if (hij < minHij || !alreadyFoundMatching) { minDomain = domain; minHij = hij; minContrFactor = contractivityFactor; minParams = parameters; //? } /* * 3.b.v. * next y. */ //firstRun = false; alreadyFoundMatching = alreadyFoundMatching || (passedContinuity && passedContractivity); } Debug.Assert(minDomain != null, "Nie uda³o siê dobraæ domeny do regionu. Wtf?!"); /* * Punkt 3.c * Find the y for which hij is a minimum */ //minimum - juz mamy /* * Punkt 3.d * If hij > Epsilon and d < dmax * then create four new regions, add them to squeue2, add the vertices of each new region to iqueue (as additional interpolation points) * and add 0 (?dlaczego 0?) to aqueue. * * else * store y with the minimum distance inside aqueue and s inside aqueue */ if (minHij > Settings.Default.EpsilonHij && region.Depth < Settings.Default.Dmax) { Region r1, r2, r3, r4; int newSize = 1 + region.Size / 2; r1 = Region.GenerateRegion(region.X, region.Y, newSize, newSize); regionsMap[r1.Left, r1.Bottom] = r1; r2 = Region.GenerateRegion(region.X + newSize - 1, region.Y, newSize, newSize); regionsMap[r2.Left, r2.Bottom] = r2; r3 = Region.GenerateRegion(region.X, region.Y + newSize - 1, newSize, newSize); regionsMap[r3.Left, r3.Bottom] = r3; r4 = Region.GenerateRegion(region.X + newSize - 1, region.Y + newSize - 1, newSize, newSize); regionsMap[r4.Left, r4.Bottom] = r4; r1.Depth = r2.Depth = r3.Depth = r4.Depth = region.Depth + 1; regionsToProcess.AddFirst(r4); regionsToProcess.AddFirst(r3); regionsToProcess.AddFirst(r2); regionsToProcess.AddFirst(r1); /* * foreach (Point p in r1.Points) { * p.Z = bitmap[p.X, p.Y]; * interpolationPoints.Enqueue(p); * } * foreach (Point p in r2.Points) { * p.Z = bitmap[p.X, p.Y]; * interpolationPoints.Enqueue(p); * } * foreach (Point p in r3.Points) { * p.Z = bitmap[p.X, p.Y]; * interpolationPoints.Enqueue(p); * } * foreach (Point p in r4.Points) { * p.Z = bitmap[p.X, p.Y]; * interpolationPoints.Enqueue(p); * } * za du¿o! :D * dochodzi tylko 5 nowych punktów (a nie 16 ;)) */ Point p1 = new Point(r1.Right, r1.Bottom, bitmap[r1.Right, r1.Bottom]); Point p2 = new Point(r1.Left, r1.Top, bitmap[r1.Left, r1.Top]); Point p3 = new Point(r1.Right, r1.Top, bitmap[r1.Right, r1.Top]); Point p4 = new Point(r4.Left, r4.Top, bitmap[r4.Left, r4.Top]); Point p5 = new Point(r4.Right, r4.Bottom, bitmap[r4.Right, r4.Bottom]); interpolationPoints.Enqueue(p1); interpolationPoints.Enqueue(p2); interpolationPoints.Enqueue(p3); interpolationPoints.Enqueue(p4); interpolationPoints.Enqueue(p5); } else { region.Domain = minDomain; region.ContractivityFactor = minContrFactor; region.Parameters = minParams; regionsProcessed.Enqueue(region); region = null; } } #endregion Console.WriteLine("Koniec kompresji"); #region Step 5) //store dmax, delta, Delta, cqueue, iqueue, aqueue ChannelData sfk = new ChannelData(); sfk.Height = height; sfk.Width = width; sfk.InterpolationPoints = interpolationPoints.ToArray(); sfk.SmallDelta = Settings.Default.SmallDelta; sfk.BigDelta = Settings.Default.BigDelta; sfk.DMax = Settings.Default.Dmax; sfk.Regions = regionsProcessed.ToArray(); return(sfk); #endregion }