Created the follow-up question follow-up question as suggested.
Created the follow-up question as suggested.
Created the follow-up question as suggested.
- read files from a directory containing images
- for each file, apply a [repetition code][1]repetition code (with n repetitions, user input)
- for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
- for each file, decode the file received from the channel and save it back as image
Any idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times. [1]
EDIT:
Created the https://en.wikipedia.org/wiki/Repetition_code follow-up question as suggested.
- read files from a directory containing images
- for each file, apply a [repetition code][1] (with n repetitions, user input)
- for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
- for each file, decode the file received from the channel and save it back as image
Any idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times. [1]: https://en.wikipedia.org/wiki/Repetition_code
- read files from a directory containing images
- for each file, apply a repetition code (with n repetitions, user input)
- for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
- for each file, decode the file received from the channel and save it back as image
Any idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times.
EDIT:
Created the follow-up question as suggested.
EDIT: I removed the old code and added the new one so be sure to check it out if you want to help me.
- read files from a directory containing images
- for each file, apply a repetition code [repetition code][1] (with n repetitions, user input)
- for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
- for each file, decode the file received from the channel and save it back as image
EDIT: The BitStream
class is from org.icepdf.core.io
package, feel free to suggest a better alternative if you wish!TestLoop
for (int i = 0; i < 15; i++) {
byte[] input = Files.readAllBytes(new File("D:\\testFrame.jpg").toPath());
String inputString = Converter.byteArrayToBitString(input);
int repetitions = 5, coefficient = 10, exponent = -3;
// Repetitions (encoding)
RepetitionCoder coder = RepetitionFactory.createRepetitionCoder(repetitions);
String repCoderOutput = coder.encode(inputString);
// Noisy channel
BaseError error = ErrorFactory.createError(coefficient, exponent);
NoisyChannel channel = new NoisyChannel(error);
String channelOutput = channel.transfer(repCoderOutput);
// Repetitions (decoding)
RepetitionDecoder decoder = RepetitionFactory.createRepetitionDecoder(repetitions);
String repDecoderOutput = decoder.decode(channelOutput);
byte[] output = Converter.bitStringToByteArray(repDecoderOutput);
Files.write(new File("D:\\testFrame_2.jpg").toPath(), output);
}
TestLoopConverter.byteArrayToBitString
for (int i = 0; i < 15; i++) {
byte[] input = Files.readAllBytes(new File("D:\\testFrame.jpg").toPath());
ByteArrayInputStream bis = new ByteArrayInputStream(input);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// Repetition coder
RepetitionCoder repCoder = RepetitionFactory.createRepetitionCoder(5);
repCoder.encode(newpublic BitStream(bis),static newString BitStreambyteArrayToBitString(bos));
bis = newbyte[] ByteArrayInputStream(bos.toByteArray()source);
bos.reset();{
NoisyChannelStringBuilder channelsb = new NoisyChannel(ErrorFactory.createErrorStringBuilder(10, -3, 0));
8 * channelsource.transfer(new BitStream(bis), new BitStream(bos)length);
bis = newfor ByteArrayInputStream(bos.toByteArray());
byte b : bos.reset(source);
// Repetition decoder{
RepetitionDecoder repDecoder = RepetitionFactory.createRepetitionDecoder(5);
repDecodersb.decode(new BitStreamappend(bis), new BitStreambyteToBitString(bosb));
// Write}
Files.write(outputFile.toPath(),return bossb.toByteArraytoString());
}
public voidString encode(BitStream in, BitStreamString outbitString){
tryreturn {repeat(bitString);
}
private whileString (in.availablerepeat() >String 0bitString) {
// Read one bit
intStringBuilder currentBitsb = innew StringBuilder(bitString.getBitslength(1);
// Output that bit* repetitions times);
for (int i = 0; ichar <c repetitions;: i++bitString.toCharArray()) {
char[] chars = new out.putBit(currentBit);char[repetitions];
Arrays.fill(chars, }c);
}
} catch sb.append(IOException exchars) {;
}
LOG.log(Level.SEVERE,return exsb.getMessagetoString(), ex);
}
}
public voidString transfer(BitStreamString input, BitStream output) throws IOException {
whilechar[] (bits = input.availabletoCharArray() > 0) {
// Read one bit;
for (int biti = input.getBits(1);
0; i < //bits.length; Applyi++) error{
int errorBitbits[i] = errorModel.addError(bitbits[i]);
// Output the altered bit}
return new output.putBitString(errorBitbits);
}
}
protected intchar addError(intchar source) {
ifreturn (isError()) {
// Flip the bit
return? flipBit(source == 0) ? 1 : 0;
}
return source;
}
protected boolean isError() {
for (int i = 0; i < Math.abs(exponent); i++) {
if (Math.random() >= 0.1) {
return false;
}
}
return !(coefficient > 0 && Math.random() >= coefficient / 10);
}
protected char flipBit(char bit) {
return (bit == '0') ? (char) 49 : (char) 48;
}
public voidString decode(BitStreamString in,bitString) BitStream{
out) throws IOException {String[] repetitionsString = splitStringEvery(bitString, repetitions);
whileStringBuilder sb = new StringBuilder(inrepetitionsString.available(length);
> 0 for (String rep : repetitionsString) {
intsb.append(majorityVote(rep));
zeroes = 0; }
return sb.toString();
}
private String[] splitStringEvery(String //s, Readint repetitionsinterval) times{
and count zeroes int arrayLength = (int) Math.ceil(((s.length() / (double) interval)));
String[] result = new forString[arrayLength];
(int ij = 0; i < repetitions; i++)int {
lastIndex = result.length - 1;
for (int i = if0; (in.getBits(1)i ==< 0lastIndex; i++) {
result[i] = s.substring(j, j + interval);
zeroes += 1;
j += interval;
}
}
result[lastIndex] = s.substring(j);
return result;
}
private char majorityVote(String buffer) {
//int Outputzeroes 0= if(int) zeroesbuffer.chars().filter(b -> repetitions/2,b 1== otherwise48).count();
return out.putBit((zeroes > repetitions / 2) ? 0'0' : 1);
}'1';
}
Any idea on how to speed things up while keeping a good readability?Converter.bitStringToByteArray
public static byte[] bitStringToByteArray(String string) {
byte[] result = new byte[string.length() / 8];
for (int i = 0; i < string.length(); i += 8) {
String subString = string.substring(i, i + 8);
result[i / 8] = bitStringToByte(subString);
}
return result;
}
EDITAny idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times. [1]: code now is way faster (almost 8 times), but it still feels slow because it does 15 images per minute (0.25 fps) and I think there's still room for improvement.https://en.wikipedia.org/wiki/Repetition_code
EDIT: I removed the old code and added the new one so be sure to check it out if you want to help me.
- read files from a directory containing images
- for each file, apply a repetition code (with n repetitions, user input)
- for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
- for each file, decode the file received from the channel and save it back as image
EDIT: The BitStream
class is from org.icepdf.core.io
package, feel free to suggest a better alternative if you wish!
TestLoop
for (int i = 0; i < 15; i++) {
byte[] input = Files.readAllBytes(new File("D:\\testFrame.jpg").toPath());
ByteArrayInputStream bis = new ByteArrayInputStream(input);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// Repetition coder
RepetitionCoder repCoder = RepetitionFactory.createRepetitionCoder(5);
repCoder.encode(new BitStream(bis), new BitStream(bos));
bis = new ByteArrayInputStream(bos.toByteArray());
bos.reset();
NoisyChannel channel = new NoisyChannel(ErrorFactory.createError(10, -3, 0));
channel.transfer(new BitStream(bis), new BitStream(bos));
bis = new ByteArrayInputStream(bos.toByteArray());
bos.reset();
// Repetition decoder
RepetitionDecoder repDecoder = RepetitionFactory.createRepetitionDecoder(5);
repDecoder.decode(new BitStream(bis), new BitStream(bos));
// Write
Files.write(outputFile.toPath(), bos.toByteArray());
}
public void encode(BitStream in, BitStream out){
try {
while (in.available() > 0) {
// Read one bit
int currentBit = in.getBits(1);
// Output that bit repetitions times
for (int i = 0; i < repetitions; i++) {
out.putBit(currentBit);
}
}
} catch (IOException ex) {
LOG.log(Level.SEVERE, ex.getMessage(), ex);
}
}
public void transfer(BitStream input, BitStream output) throws IOException {
while (input.available() > 0) {
// Read one bit
int bit = input.getBits(1);
// Apply error
int errorBit = errorModel.addError(bit);
// Output the altered bit
output.putBit(errorBit);
}
}
protected int addError(int source) {
if (isError()) {
// Flip the bit
return (source == 0) ? 1 : 0;
}
return source;
}
protected boolean isError() {
for (int i = 0; i < Math.abs(exponent); i++) {
if (Math.random() >= 0.1) {
return false;
}
}
return !(coefficient > 0 && Math.random() >= coefficient / 10);
}
public void decode(BitStream in, BitStream out) throws IOException {
while (in.available() > 0) {
int zeroes = 0;
// Read repetitions times and count zeroes
for (int i = 0; i < repetitions; i++) {
if (in.getBits(1) == 0) {
zeroes += 1;
}
}
// Output 0 if zeroes > repetitions/2, 1 otherwise
out.putBit((zeroes > repetitions / 2) ? 0 : 1);
}
}
Any idea on how to speed things up while keeping a good readability?
EDIT: code now is way faster (almost 8 times), but it still feels slow because it does 15 images per minute (0.25 fps) and I think there's still room for improvement.
- read files from a directory containing images
- for each file, apply a [repetition code][1] (with n repetitions, user input)
- for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
- for each file, decode the file received from the channel and save it back as image
TestLoop
for (int i = 0; i < 15; i++) {
byte[] input = Files.readAllBytes(new File("D:\\testFrame.jpg").toPath());
String inputString = Converter.byteArrayToBitString(input);
int repetitions = 5, coefficient = 10, exponent = -3;
// Repetitions (encoding)
RepetitionCoder coder = RepetitionFactory.createRepetitionCoder(repetitions);
String repCoderOutput = coder.encode(inputString);
// Noisy channel
BaseError error = ErrorFactory.createError(coefficient, exponent);
NoisyChannel channel = new NoisyChannel(error);
String channelOutput = channel.transfer(repCoderOutput);
// Repetitions (decoding)
RepetitionDecoder decoder = RepetitionFactory.createRepetitionDecoder(repetitions);
String repDecoderOutput = decoder.decode(channelOutput);
byte[] output = Converter.bitStringToByteArray(repDecoderOutput);
Files.write(new File("D:\\testFrame_2.jpg").toPath(), output);
}
Converter.byteArrayToBitString
public static String byteArrayToBitString(byte[] source) {
StringBuilder sb = new StringBuilder(8 * source.length);
for (byte b : source) {
sb.append(byteToBitString(b));
}
return sb.toString();
}
public String encode(String bitString){
return repeat(bitString);
}
private String repeat(String bitString) {
StringBuilder sb = new StringBuilder(bitString.length() * repetitions);
for (char c : bitString.toCharArray()) {
char[] chars = new char[repetitions];
Arrays.fill(chars, c);
sb.append(chars);
}
return sb.toString();
}
public String transfer(String input) {
char[] bits = input.toCharArray();
for (int i = 0; i < bits.length; i++) {
bits[i] = errorModel.addError(bits[i]);
}
return new String(bits);
}
protected char addError(char source) {
return (isError()) ? flipBit(source) : source;
}
protected boolean isError() {
for (int i = 0; i < Math.abs(exponent); i++) {
if (Math.random() >= 0.1) {
return false;
}
}
return !(coefficient > 0 && Math.random() >= coefficient / 10);
}
protected char flipBit(char bit) {
return (bit == '0') ? (char) 49 : (char) 48;
}
public String decode(String bitString) {
String[] repetitionsString = splitStringEvery(bitString, repetitions);
StringBuilder sb = new StringBuilder(repetitionsString.length);
for (String rep : repetitionsString) {
sb.append(majorityVote(rep));
}
return sb.toString();
}
private String[] splitStringEvery(String s, int interval) {
int arrayLength = (int) Math.ceil(((s.length() / (double) interval)));
String[] result = new String[arrayLength];
int j = 0; int lastIndex = result.length - 1;
for (int i = 0; i < lastIndex; i++) {
result[i] = s.substring(j, j + interval);
j += interval;
}
result[lastIndex] = s.substring(j);
return result;
}
private char majorityVote(String buffer) {
int zeroes = (int) buffer.chars().filter(b -> b == 48).count();
return (zeroes > repetitions / 2) ? '0' : '1';
}
Converter.bitStringToByteArray
public static byte[] bitStringToByteArray(String string) {
byte[] result = new byte[string.length() / 8];
for (int i = 0; i < string.length(); i += 8) {
String subString = string.substring(i, i + 8);
result[i / 8] = bitStringToByte(subString);
}
return result;
}
Any idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times. [1]: https://en.wikipedia.org/wiki/Repetition_code