/* Returns the amount of error compared to a given block at the current position */ public double getErrorForPosition(double[,] image, Block comparison, int xPos, int yPos, int channel) { xPos -= 4; yPos -= 4; double error = 0; double pixelValue; double currentError; Color color = new Color(); switch (channel) { case 1: YerrorBlock = new Block(); break; case 2: CberrorBlock = new Block(); break; case 3: CrerrorBlock = new Block(); break; } for (int y=yPos; y<yPos+8; y++) { for (int x=xPos; x<xPos+8; x++) { //if out of bounds, treat as a value of zero if (y >= image.GetLength(1) || x >= image.GetLength(0)||x<0||y<0) { switch (channel) { case 1: YerrorBlock.set(x - xPos, y - yPos, Math.Round(0 - comparison.get(x - xPos, y - yPos))); break; case 2: CberrorBlock.set(x - xPos, y - yPos, Math.Round((0 - comparison.get(x - xPos, y - yPos)))); break; case 3: CrerrorBlock.set(x - xPos, y - yPos, Math.Round((0 - comparison.get(x - xPos, y - yPos)))); break; } error += Math.Abs(0 - comparison.get(x - xPos, y - yPos)); continue; } currentError = image[x,y]-comparison.get(x-xPos, y-yPos); error += Math.Abs(currentError); switch (channel) { case 1: YerrorBlock.set(x - xPos, y - yPos, Math.Round(currentError)); break; case 2: CberrorBlock.set(x - xPos, y - yPos, Math.Round(currentError)); break; case 3: CrerrorBlock.set(x - xPos, y - yPos, Math.Round(currentError)); break; } } } if (xPos == 3 && yPos == 0) { //Debug.WriteLine("----------------------------ErrorBlock-----------------------------------"); for (int q = 0; q < 8; q++) { for (int w = 0; w < 8; w++) { //Debug.Write(errorBlock.get(q, w) + ","); //Debug.Write(comparison.get(q, w) + ","); } // Debug.WriteLine(""); } // Debug.WriteLine("----------------------------------------------------------------------------------------------"); } error /= 64; // Debug.WriteLine("Total error = "+error); return error; }
/* Returns the amount of error compared to a given block at the current position */ public void getOriginalFromError(double[,] image, Block errorBlock, int xPos, int yPos, int channel) { xPos -= 4; yPos -= 4; double error = 0; double pixelValue; double currentError; Color color = new Color(); switch (channel) { case 1: YpostBlock = new Block(); break; case 2: CbpostBlock = new Block(); break; case 3: CrpostBlock = new Block(); break; } for (int y = yPos; y < yPos + 8; y++) { for (int x = xPos; x < xPos + 8; x++) { //if out of bounds, treat as a value of zero if (y >= image.GetLength(1) || x >= image.GetLength(0) || x < 0 || y < 0) { switch (channel) { case 1: YpostBlock.set(x - xPos, y - yPos, Math.Round(Math.Abs(0 + errorBlock.get(x - xPos, y - yPos)))); break; case 2: CbpostBlock.set(x - xPos, y - yPos, Math.Round(Math.Abs(0 + errorBlock.get(x - xPos, y - yPos)))); break; case 3: CrpostBlock.set(x - xPos, y - yPos, Math.Round(Math.Abs(0 + errorBlock.get(x - xPos, y - yPos)))); break; } continue; } currentError = Math.Abs(image[x, y] + errorBlock.get(x - xPos, y - yPos)); switch (channel) { case 1: YerrorBlock.set(x - xPos, y - yPos, Math.Round(currentError)); break; case 2: CbpostBlock.set(x - xPos, y - yPos, Math.Round(currentError)); break; case 3: CrpostBlock.set(x - xPos, y - yPos, Math.Round(currentError)); break; } } } }
/* undoes zig zag on an int array, and outputs the original 8x8 block */ public Block undoZigZag(int[] array) { Block block = new Block(); int arrayPos = 0; int yMove = -1; int xMove = 1; int x = 0; int y = 0; block.set(x, y, array[arrayPos++]); for (int level = 0; level < 8; level++) { for (int depth = 0; depth < level; depth++) { x += xMove; y += yMove; block.set(x, y, array[arrayPos++]); } if (level == 7) break; if (xMove < 0) y++; else x++; block.set(x, y, array[arrayPos++]); yMove *= -1; xMove *= -1; } yMove *= -1; xMove *= -1; if (xMove < 0) y++; else x++; block.set(x, y, array[arrayPos++]); for (int level = 6; level > 0; level--) { for (int depth = level; depth > 0; depth--) { x += xMove; y += yMove; block.set(x, y, array[arrayPos++]); } if (xMove < 0) x++; else y++; block.set(x, y, array[arrayPos++]); yMove *= -1; xMove *= -1; } return block; }
/* Multiplies the values of a quantized block by a quantization table to undo quantization. returns the outcome */ public Block RemoveQuantization(Block block, int[,] table) { Block quantizedBlock = new Block(); for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { quantizedBlock.set(x, y, block.get(x, y) * table[x, y]); } } return quantizedBlock; }
/* Divides the values of the block by a passed quantization table, and returns the outcome */ public Block applyQuantization(Block block, int[,] table) { Block quantizedBlock = new Block(); for (int y=0; y<8; y++) { for (int x=0; x<8; x++) { quantizedBlock.set(x,y,Math.Round((double)block.get(x, y) / table[x, y])); } } return quantizedBlock; }
/* Generates an 8x8 block from a position */ public Block generateBlock(double[,] fullSize, int xPosition, int yPosition) { Block block = new Block(); for (int y=yPosition; y<yPosition+8; y++) { for (int x=xPosition; x<xPosition+8; x++) { if (x < fullSize.GetLength(0) && y < fullSize.GetLength(1)) { block.set(x-xPosition,y-yPosition,fullSize[x,y]); } else { block.set(x - xPosition, y - yPosition, 0.0); } } } return block; }