private static void HandleFirstPixel(ImageMatrices imageMatrices, NearLosslessOptions nearLosslessOptions) { var halfway = (nearLosslessOptions.PredictionUpperLimit - nearLosslessOptions.PredictionLowerLimit) / 2.0; var rounded = (int)Math.Ceiling(halfway); HandlePrediction(imageMatrices, nearLosslessOptions, 0, 0, rounded.ToAbsoluteByte(nearLosslessOptions.PredictionLowerLimit, nearLosslessOptions.PredictionUpperLimit)); }
private void WriteOptions(NearLosslessOptions nearLosslessOptions) { fileWriter.WriteValueOnBits((uint)nearLosslessOptions.PredictorType, 4); fileWriter.WriteValueOnBits((uint)nearLosslessOptions.AcceptedError, 4); fileWriter.WriteValueOnBits((uint)nearLosslessOptions.SaveMode, 3); fileWriter.WriteValueOnBits(nearLosslessOptions.PredictionLowerLimit, 8); fileWriter.WriteValueOnBits(nearLosslessOptions.PredictionUpperLimit, 8); }
private static void HandleFirstRow(ImageMatrices imageMatrices, NearLosslessOptions nearLosslessOptions, INearLosslessPredictor predictor) { const byte a = 0; const byte c = 0; for (var column = 1; column < imageMatrices.Height; column++) { var b = imageMatrices.Decoded[0, column - 1]; var prediction = predictor.PredictValue(nearLosslessOptions.PredictionLowerLimit, nearLosslessOptions.PredictionUpperLimit, a, b, c); HandlePrediction(imageMatrices, nearLosslessOptions, 0, column, prediction); } }
private static void HandleFirstColumn(ImageMatrices imageMatrices, NearLosslessOptions nearLosslessOptions, INearLosslessPredictor predictor) { const byte b = 0; const byte c = 0; for (var row = 1; row < imageMatrices.Width; row++) { var a = imageMatrices.Decoded[row - 1, 0]; var prediction = predictor.PredictValue(nearLosslessOptions.PredictionLowerLimit, nearLosslessOptions.PredictionUpperLimit, a, b, c); HandlePrediction(imageMatrices, nearLosslessOptions, row, 0, prediction); } }
private static void HandlePrediction(ImageMatrices imageMatrices, NearLosslessOptions nearLosslessOptions, int row, int column, byte prediction) { var k = nearLosslessOptions.AcceptedError; var error = imageMatrices.Codes[row, column] - prediction; var quantizedError = Quantize(error, k); var dequantizedError = Dequantize(quantizedError, k); var decoded = GetByte(dequantizedError + prediction, nearLosslessOptions.PredictionLowerLimit, nearLosslessOptions.PredictionUpperLimit); imageMatrices.Predictions[row, column] = prediction; imageMatrices.Errors[row, column] = error; imageMatrices.QuantizedErrors[row, column] = quantizedError; imageMatrices.DequantizedErrors[row, column] = dequantizedError; imageMatrices.Decoded[row, column] = decoded; }
public void Encode(string sourceFilepath, string destinationFilepath, NearLosslessOptions nearLosslessOptions) { var image = GetImageOrThrow(sourceFilepath); var imageMatrices = new ImageMatrices(image); image.Dispose(); PredictionMatrixHelper.SetImageMatrices(imageMatrices, nearLosslessOptions); fileReader.Open(sourceFilepath); fileWriter.Open(destinationFilepath); CopyBitmapHeader(); WriteOptions(nearLosslessOptions); var errorMatrixWriter = NearLosslessErrorMatrixWriterSelector.GetErrorMatrixWriter(nearLosslessOptions.SaveMode); errorMatrixWriter.WriteErrorMatrix(imageMatrices.QuantizedErrors, fileWriter); fileWriter.Flush(); fileReader.Close(); fileWriter.Close(); }
public static void SetImageMatrices(ImageMatrices imageMatrices, NearLosslessOptions nearLosslessOptions) { var predictor = NearLosslessPredictorSelector.GetPredictor(nearLosslessOptions.PredictorType); HandleFirstPixel(imageMatrices, nearLosslessOptions); HandleFirstColumn(imageMatrices, nearLosslessOptions, predictor); HandleFirstRow(imageMatrices, nearLosslessOptions, predictor); for (var row = 1; row < imageMatrices.Width; row++) { for (var column = 1; column < imageMatrices.Height; column++) { var a = imageMatrices.Decoded[row - 1, column]; var b = imageMatrices.Decoded[row, column - 1]; var c = imageMatrices.Decoded[row - 1, column - 1]; var prediction = predictor.PredictValue(nearLosslessOptions.PredictionLowerLimit, nearLosslessOptions.PredictionUpperLimit, a, b, c); HandlePrediction(imageMatrices, nearLosslessOptions, row, column, prediction); } } }
private void SetupCase1() { options = new NearLosslessOptions { AcceptedError = 2, PredictorType = NearLosslessPredictorType.Predictor4, PredictionLowerLimit = 0, PredictionUpperLimit = 15 }; imageMatrices = new ImageMatrices(4, 4); expectedImageMatrices = new ImageMatrices(4, 4); var imageCodes = new byte[, ] { { 7, 5, 2, 0 }, { 2, 11, 1, 0 }, { 15, 15, 15, 0 }, { 1, 4, 14, 14 } }; var expectedPredictions = new byte[, ] { { 8, 8, 3, 3 }, { 8, 0, 10, 0 }, { 3, 15, 5, 15 }, { 13, 5, 5, 0 } }; var expectedErrors = new int[, ] { { -1, -3, -1, -3 }, { -6, 11, -9, 0 }, { 12, 0, 10, -15 }, { -12, -1, 9, 14 } }; var expectedQuantizedErrors = new int[, ] { { 0, -1, 0, -1 }, { -1, 2, -2, 0 }, { 2, 0, 2, -3 }, { -2, 0, 2, 3 } }; var expectedDequantizedErrors = new int[, ] { { 0, -5, 0, -5 }, { -5, 10, -10, 0 }, { 10, 0, 10, -15 }, { -10, 0, 10, 15 } }; var expectedDecoded = new byte[, ] { { 8, 3, 3, 0 }, { 3, 10, 0, 0 }, { 13, 15, 15, 0 }, { 3, 5, 15, 15 } }; CopyMatrix(imageCodes, imageMatrices.Codes); CopyMatrix(imageCodes, expectedImageMatrices.Codes); CopyMatrix(expectedPredictions, expectedImageMatrices.Predictions); CopyMatrix(expectedErrors, expectedImageMatrices.Errors); CopyMatrix(expectedQuantizedErrors, expectedImageMatrices.QuantizedErrors); CopyMatrix(expectedDequantizedErrors, expectedImageMatrices.DequantizedErrors); CopyMatrix(expectedDecoded, expectedImageMatrices.Decoded); }
public static ImageMatrices GetImageMatricesFromQuantizedErrorMatrix(int[,] quantizedErrors, NearLosslessOptions nearLosslessOptions) { var predictor = NearLosslessPredictorSelector.GetPredictor(nearLosslessOptions.PredictorType); var imageMatrices = new ImageMatrices(quantizedErrors.GetLength(0), quantizedErrors.GetLength(1)); CopyMatrix(quantizedErrors, imageMatrices.QuantizedErrors); HandleFirstPixel(imageMatrices, nearLosslessOptions); HandleFirstColumn(imageMatrices, nearLosslessOptions, predictor); HandleFirstRow(imageMatrices, nearLosslessOptions, predictor); for (var row = 1; row < imageMatrices.Width; row++) { for (var column = 1; column < imageMatrices.Height; column++) { var a = imageMatrices.Decoded[row - 1, column]; var b = imageMatrices.Decoded[row, column - 1]; var c = imageMatrices.Decoded[row - 1, column - 1]; var prediction = predictor.PredictValue(nearLosslessOptions.PredictionLowerLimit, nearLosslessOptions.PredictionUpperLimit, a, b, c); HandlePrediction(imageMatrices, nearLosslessOptions, row, column, prediction); } } return(imageMatrices); }