private void calculateDCTForBlock(YCrCb[,] matrix, int x, int y) { var tempMatrix = new YCrCb[BlockSize,BlockSize]; for (int k = 0; k < BlockSize; k++) { for (int l = 0; l < BlockSize; l++) { double sumY = 0, sumCr = 0, sumCb = 0; for (int i = 0; i < BlockSize; i++) { for (int j = 0; j < BlockSize; j++) { sumY += coefficient(k)*coefficient(l)*matrix[i + x, j + y].Y*calculateCosine(k, i)* calculateCosine(l, j)/4; sumCr += coefficient(k)*coefficient(l)*matrix[i + x, j + y].Cr*calculateCosine(k, i)* calculateCosine(l, j)/4; sumCb += coefficient(k)*coefficient(l)*matrix[i + x, j + y].Cb*calculateCosine(k, i)* calculateCosine(l, j)/4; } } tempMatrix[k, l].Y = Math.Round(sumY, 1); tempMatrix[k, l].Cr = Math.Round(sumCr, 2); tempMatrix[k, l].Cb = Math.Round(sumCb, 2); } } copyTempMatrixToRealMatrix(x, y, matrix, tempMatrix); }
public static void PrintMatrix(string name, YCrCb[,] matrix) { Console.WriteLine(name + " Y "); for (int i = 0; i < matrix.GetLength(0); i++) { for (int j = 0; j < matrix.GetLength(1); j++) { Console.Write((matrix[i, j].Y).ToString().PadLeft(6, ' ')); } Console.WriteLine(); } Console.WriteLine(); //Console.WriteLine(name + " Cr "); //for (int i = 0; i < matrix.GetLength(0); i++) //{ // for (int j = 0; j < matrix.GetLength(1); j++) // { // Console.Write((matrix[i, j].Cr).ToString().PadLeft(10, ' ')); // } // Console.WriteLine(); //} //Console.WriteLine(); //Console.WriteLine(name + " Cb "); //for (int i = 0; i < matrix.GetLength(0); i++) //{ // for (int j = 0; j < matrix.GetLength(1); j++) // { // Console.Write((matrix[i, j].Cb).ToString().PadLeft(10, ' ')); // } // Console.WriteLine(); //} //Console.WriteLine(); }
public static RGB Parse(YCrCb yCrCb) { return new RGB { R = calculateRed(yCrCb), B = calculateBlue(yCrCb), G = calculateGreen(yCrCb) }; }
public void Supersample(YCrCb[,] matrix) { for (int i = 0; i < matrix.GetLength(0); i++) { for (int j = 0; j < matrix.GetLength(1); j++) { matrix[i, j].Y += 128; matrix[i, j].Cr += 128; matrix[i, j].Cb += 128; } } }
private YCrCb[,] convertToYCrCb(double[,] matrix) { var convertedMatrix = new YCrCb[8,8]; for (int m = 0; m < 8; m++) { for (int n = 0; n < 8; n++) { convertedMatrix[m, n] = new YCrCb {Y = matrix[m, n]}; } } return convertedMatrix; }
private double[,] convertToDouble(YCrCb[,] expectedMatrix) { var convertedMatrix = new double[8,8]; for (int m = 0; m < 8; m++) { for (int n = 0; n < 8; n++) { convertedMatrix[m, n] = expectedMatrix[m, n].Y; } } return convertedMatrix; }
public void CalculateIDCT(YCrCb[,] matrix) { int width = matrix.GetLength(0); int height = matrix.GetLength(1); for (int x = 0; x < width; x = x + BlockSize) { for (int y = 0; y < height; y = y + BlockSize) { calculateIDCTForBlock(matrix, x, y); } } }
private int bitsPerNonZeroDCTCoefficient(YCrCb[,] matrix) { int count = 0; for (int i = 0; i < matrix.GetLength(0); i++) { for (int j = 0; j < matrix.GetLength(1); j++) { if (matrix[i, j].Y != 0 && matrix[i, j].Y != 1) { count++; } } } return count; }
public static YCrCb[,] Parse(RGB[,] rgb) { int m = rgb.GetLength(0); int n = rgb.GetLength(1); var matrix = new YCrCb[m, n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { matrix[i, j] = Parse(rgb[i, j]); } } return matrix; }
public List<Point> Permutation(YCrCb[,] matrix) { var points = new List<Point>(); for (int i = 0; i < matrix.GetLength(0); i++) { for (int j = 0; j < matrix.GetLength(1); j++) { if (matrix[i, j].Y != 0 && matrix[i, j].Y != 1) { points.Add(new Point(i, j)); } } } return points; }
public static RGB[,] Parse(YCrCb[,] yCrCb) { int m = yCrCb.GetLength(0); int n = yCrCb.GetLength(1); var matrix = new RGB[m, n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { matrix[i, j] = Parse(yCrCb[i, j]); } } return matrix; }
public void ApplyQuantization(YCrCb[,] matrix, int qualityFactor) { int i, j, k, l; int[,] qualityLuminanceMatrix = generateQualityFactorLuminanceMatrix(qualityFactor); int[,] qualityChrominanceMatrix = generateQualityFactorChrominanceMatrix(qualityFactor); for (i = 0; i < matrix.GetLength(0); i++) { k = i % 8; for (j = 0; j < matrix.GetLength(1); j++) { l = j % 8; matrix[i, j].Y = Math.Round(matrix[i, j].Y / qualityLuminanceMatrix[k, l]); matrix[i, j].Cr = Math.Round(matrix[i, j].Cr / qualityChrominanceMatrix[k, l]); matrix[i, j].Cb = Math.Round(matrix[i, j].Cb / qualityChrominanceMatrix[k, l]); } } }
public void HideMessage(YCrCb[,] matrix, byte[] message) { if (bitsPerNonZeroDCTCoefficient(matrix) - 32 < message.Length * 8) throw new ArgumentException("Message too long to be embedded."); var path = Permutation(matrix); var bitsFromSizeField = new BitArray(BitConverter.GetBytes(message.Length * 8)); int i = 0; foreach (var bit in bitsFromSizeField) { matrix[path[i].X, path[i].Y].Y = calculateLSB(matrix[path[i].X, path[i].Y].Y, Convert.ToInt32(bit)); i++; } var bitsFromDataField = new BitArray(message); i = 32; foreach (var bit in bitsFromDataField) { matrix[path[i].X, path[i].Y].Y = calculateLSB(matrix[path[i].X, path[i].Y].Y, Convert.ToInt32(bit)); i++; } }
public byte[] ExtractMessage(YCrCb[,] matrix) { var path = Permutation(matrix); var pathIndex = 0; var bitsFromSizeField = new BitArray(32); for (pathIndex = 0; pathIndex < bitsFromSizeField.Length; pathIndex++) { int lsb = ((int) matrix[path[pathIndex].X, path[pathIndex].Y].Y)%2; bitsFromSizeField.Set(pathIndex, lsb != 0); } var bytesFromSizeField = new byte[4]; bitsFromSizeField.CopyTo(bytesFromSizeField, 0); int sizeField = BitConverter.ToInt32(bytesFromSizeField, 0); var bitsFromDataField = new BitArray(sizeField); for (int i = 0; i < sizeField; i++, pathIndex++) bitsFromDataField.Set(i, ((int)matrix[path[pathIndex].X, path[pathIndex].Y].Y) % 2 != 0); var bytesFromDataField = new byte[(int)Math.Ceiling(sizeField / 8.0)]; bitsFromDataField.CopyTo(bytesFromDataField, 0); return bytesFromDataField; }
private static double calculateBlue(YCrCb yCrCb) { return Math.Round(yCrCb.Y + 1.772*(yCrCb.Cb - 128)).ToByteBounds(); }
private static double calculateGreen(YCrCb yCrCb) { return Math.Round(yCrCb.Y - 0.34414*(yCrCb.Cb - 128) - 0.71414*(yCrCb.Cr - 128)).ToByteBounds(); }
private static double calculateRed(YCrCb yCrCb) { return Math.Round(yCrCb.Y + 1.402 * (yCrCb.Cr - 128)).ToByteBounds() ; }
private void copyTempMatrixToRealMatrix(int x, int y, YCrCb[,] matrix, YCrCb[,] tempMatrix) { for (int i = 0; i < BlockSize; i++) { for (int j = 0; j < BlockSize; j++) { matrix[i + x, j + y].Y = tempMatrix[i, j].Y; matrix[i + x, j + y].Cb = tempMatrix[i, j].Cb; matrix[i + x, j + y].Cr = tempMatrix[i, j].Cr; } } }