private void Decompress(object i) { try { while (!Cancelled) { ByteBlock _block = QueueReader.Dequeue(); if (_block == null) { return; } using (MemoryStream ms = new MemoryStream(_block.CompressedBuffer)) { using (GZipStream _gz = new GZipStream(ms, CompressionMode.Decompress)) { _gz.Read(_block.Buffer, 0, _block.Buffer.Length); byte[] decompressedData = _block.Buffer.ToArray(); ByteBlock block = new ByteBlock(_block.ID, decompressedData); QueueWriter.EnqueueForWriting(block); } } } } catch (Exception ex) { Console.WriteLine("Error in thread number {0}. \n Error description: {1}", i, ex.Message); Cancelled = true; } }
private void Compress(object i) { try { while (!Cancelled) { ByteBlock _block = QueueReader.Dequeue(); if (_block == null) { return; } using (MemoryStream _memoryStream = new MemoryStream()) { using (GZipStream cs = new GZipStream(_memoryStream, CompressionMode.Compress)) { cs.Write(_block.Buffer, 0, _block.Buffer.Length); } byte[] compressedData = _memoryStream.ToArray(); ByteBlock _out = new ByteBlock(_block.ID, compressedData); QueueWriter.EnqueueForWriting(_out); } WaitHandle doneEvent = DoneEvents[(int)i]; doneEvent.Dispose(); } } catch (Exception ex) { Console.WriteLine("Ошибка в номере потока {0}. \n описание ошибки: {1}", i, ex.Message); Cancelled = true; } }
/*private static void EnqueueShortAsBytes(ByteWriter output, short value) { //output.WriteByteShort(value); //output.Enqueue((byte)(value >> 8)); //output.Enqueue((byte)(value & 0xFF)); }*/ private static short DequeueShortAsBytes(QueueReader<byte> input) { return (short)((input.Dequeue() << 8) | input.Dequeue()); }
//public static void DecompressQuadTree(short[,] output, QueueReader<byte> input, short x, short y, short width, short height) public static void DecompressQuadTree(short[,] output, QueueReader<byte> input, short x1, short y1, short x2, short y2) { short width = (short)(x2 - x1); short height = (short)(y2 - y1); short middleX; short middleY; int binaryDataByte; //byte id; if (width == 0 || height == 0) return; if (width <= 2 && height <= 2) { for (int yy = y1; yy < y2; yy++) //output[x, y] = input.Dequeue(); { for (int xx = x1; xx < x2; xx++) output[xx, yy] = (short)((input.Dequeue()<<8) | input.Dequeue()); } return; } middleX = (short)(x1 + (width >> 1));//(x1) - (x1+x2 >> 1); middleY = (short)(y1 + (height >> 1));//(y1) - (y1+y2 >> 1); binaryDataByte = input.Dequeue(); Action<byte> lambda = new Action<byte>(b => { short l_x1; short l_y1; short l_x2; short l_y2; short l_id; switch (b) { case 0: l_x1 = x1; l_y1 = y1; l_x2 = middleX; l_y2 = middleY; break; case 1: l_x1 = middleX; l_y1 = y1; l_x2 = x2; l_y2 = middleY; break; case 2: l_x1 = x1; l_y1 = middleY; l_x2 = middleX; l_y2 = y2; break; case 3: //strong x, strong y l_x1 = middleX; l_y1 = middleY; l_x2 = x2; l_y2 = y2; break; default: throw new Exception(b.ToString() + " is an invalid quadtree child index. It can only be 0,1,2 or 3."); } if ((binaryDataByte & (1 << b)) == (1 << b)) { l_id = DequeueShortAsBytes(input); for (int yy = l_y1; yy < l_y2; yy++) { for (int xx = l_x1; xx < l_x2; xx++) output[xx, yy] = l_id; } } else { DecompressQuadTree(output, input, l_x1, l_y1, l_x2, l_y2); } }); lambda(0); lambda(1); lambda(2); lambda(3); }
public static void DecompressBinaryTree(short[] output, QueueReader<byte> input, short start, short end) { short length = (short)(start - end); short middle; //tells if the children are simple(true) or complex(false). byte binaryDataByte; short id; if (length <= 2) { if (length == 0) return; if (length == 1) { output[start] = DequeueShortAsBytes(input); } else // length must be 2 { output[start] = DequeueShortAsBytes(input); output[start + 1] = DequeueShortAsBytes(input); } return; } middle = (short)(start + length / 2); binaryDataByte = input.Dequeue(); if ((binaryDataByte & 1) == 1) { id = DequeueShortAsBytes(input); for (int i = start; i < middle; i++) output[i] = id; } else { DecompressBinaryTree(output, input, start, middle); } if ((binaryDataByte & 2) == 2) { id = DequeueShortAsBytes(input); for (int i = middle; i < end; i++) output[i] = id; } else { DecompressBinaryTree(output, input, middle, end); } }