X-Git-Url: http://www2.svjatoslav.eu/gitweb/?p=imagesqueeze.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Feu%2Fsvjatoslav%2Fimagesqueeze%2Fcodec%2FImageEncoder.java;h=f93f9182d1b9418f159228ff55bf7c34e7279a5e;hp=5b0e8db5f85a28a5b8607c118aa0a6d73091404b;hb=4595d6b97aff8e6d9dcce902bc2f1119d4ab2f0e;hpb=a4acb4f31760b0c654f9a041eef9797782d6043a diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java index 5b0e8db..f93f918 100755 --- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java +++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java @@ -1,10 +1,9 @@ /* - * Imagesqueeze - Image codec optimized for photos. - * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu + * Imagesqueeze - Image codec. Copyright ©2012-2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. + * modify it under the terms of version 3 of the GNU Lesser General Public License + * or later as published by the Free Software Foundation. */ package eu.svjatoslav.imagesqueeze.codec; @@ -13,529 +12,523 @@ package eu.svjatoslav.imagesqueeze.codec; * Compressed image pixels encoder. */ +import eu.svjatoslav.commons.data.BitOutputStream; + import java.awt.image.DataBufferByte; import java.awt.image.WritableRaster; import java.io.IOException; -import eu.svjatoslav.commons.data.BitOutputStream; - -public class ImageEncoder { - - public static int byteToInt(final byte input) { - int result = input; - if (result < 0) - result = result + 256; - return result; - } - - public static int decodeValueFromGivenBits(final int encodedBits, - final int range, final int bitCount) { - final int negativeBit = encodedBits & 1; - - final int remainingBitCount = bitCount - 1; - - if (remainingBitCount == 0) { - // no more bits remaining to encode actual value - - if (negativeBit == 0) - return range; - else - return -range; - - } else { - // still one or more bits left, encode value as precisely as - // possible - - final int encodedValue = (encodedBits >>> 1) + 1; - - final int realvalueForThisBitcount = 1 << remainingBitCount; - - // int valueMultiplier = range / realvalueForThisBitcount; - int decodedValue = (range * encodedValue) - / realvalueForThisBitcount; - - if (decodedValue > range) - decodedValue = range; - - if (negativeBit == 0) - return decodedValue; - else - return -decodedValue; +class ImageEncoder { - } - } + private final Image image; + private final Approximator approximator; + // ColorStats colorStats = new ColorStats(); + private final OperatingContext context = new OperatingContext(); + private final OperatingContext context2 = new OperatingContext(); + int bitsForY; + int bitsForU; + int bitsForV; + private int width; + private int height; + private Channel yChannel; + private Channel uChannel; + private Channel vChannel; + private BitOutputStream bitOutputStream; - public static int encodeValueIntoGivenBits(int value, final int range, - final int bitCount) { + public ImageEncoder(final Image image) { + approximator = new Approximator(); - int negativeBit = 0; + // bitOutputStream = outputStream; - if (value < 0) { - negativeBit = 1; - value = -value; - } + this.image = image; - final int remainingBitCount = bitCount - 1; + } - if (remainingBitCount == 0) - return negativeBit; - else { - // still one or more bits left, encode value as precisely as - // possible + public static int byteToInt(final byte input) { + int result = input; + if (result < 0) + result = result + 256; + return result; + } - if (value > range) - value = range; + public static int decodeValueFromGivenBits(final int encodedBits, + final int range, final int bitCount) { + final int negativeBit = encodedBits & 1; - final int realvalueForThisBitcount = 1 << remainingBitCount; - // int valueMultiplier = range / realvalueForThisBitcount; - int encodedValue = (value * realvalueForThisBitcount) / range; + final int remainingBitCount = bitCount - 1; - if (encodedValue >= realvalueForThisBitcount) - encodedValue = realvalueForThisBitcount - 1; + if (remainingBitCount == 0) { + // no more bits remaining to encode actual value - encodedValue = (encodedValue << 1) + negativeBit; + if (negativeBit == 0) + return range; + else + return -range; - return encodedValue; - } - } + } else { + // still one or more bits left, encode value as precisely as + // possible - public static void storeIntegerCompressed8( - final BitOutputStream outputStream, final int data) - throws IOException { + final int encodedValue = (encodedBits >>> 1) + 1; - if (data < 256) { - outputStream.storeBits(0, 1); - outputStream.storeBits(data, 8); - } else { - outputStream.storeBits(1, 1); - outputStream.storeBits(data, 32); - } - } + final int realvalueForThisBitcount = 1 << remainingBitCount; - Image image; - int width, height; + // int valueMultiplier = range / realvalueForThisBitcount; + int decodedValue = (range * encodedValue) + / realvalueForThisBitcount; - Channel yChannel; + if (decodedValue > range) + decodedValue = range; - Channel uChannel; - Channel vChannel; - Approximator approximator; + if (negativeBit == 0) + return decodedValue; + else + return -decodedValue; - int bitsForY; - int bitsForU; + } + } - int bitsForV; + private static int encodeValueIntoGivenBits(int value, final int range, + final int bitCount) { - // ColorStats colorStats = new ColorStats(); - OperatingContext context = new OperatingContext(); + int negativeBit = 0; - OperatingContext context2 = new OperatingContext(); + if (value < 0) { + negativeBit = 1; + value = -value; + } - BitOutputStream bitOutputStream; + final int remainingBitCount = bitCount - 1; - public ImageEncoder(final Image image) { - approximator = new Approximator(); + if (remainingBitCount == 0) + return negativeBit; + else { + // still one or more bits left, encode value as precisely as + // possible - // bitOutputStream = outputStream; + if (value > range) + value = range; - this.image = image; + final int realvalueForThisBitcount = 1 << remainingBitCount; + // int valueMultiplier = range / realvalueForThisBitcount; + int encodedValue = (value * realvalueForThisBitcount) / range; - } + if (encodedValue >= realvalueForThisBitcount) + encodedValue = realvalueForThisBitcount - 1; - public void encode(final BitOutputStream bitOutputStream) - throws IOException { - this.bitOutputStream = bitOutputStream; + encodedValue = (encodedValue << 1) + negativeBit; - approximator.initialize(); + return encodedValue; + } + } - approximator.save(bitOutputStream); + public static void storeIntegerCompressed8( + final BitOutputStream outputStream, final int data) + throws IOException { - width = image.metaData.width; - height = image.metaData.height; + if (data < 256) { + outputStream.storeBits(0, 1); + outputStream.storeBits(data, 8); + } else { + outputStream.storeBits(1, 1); + outputStream.storeBits(data, 32); + } + } - final WritableRaster raster = image.bufferedImage.getRaster(); - final DataBufferByte dbi = (DataBufferByte) raster.getDataBuffer(); - final byte[] pixels = dbi.getData(); + public void encode(final BitOutputStream bitOutputStream) + throws IOException { + this.bitOutputStream = bitOutputStream; - if (yChannel == null) - yChannel = new Channel(width, height); - else - yChannel.reset(); + approximator.initialize(); - if (uChannel == null) - uChannel = new Channel(width, height); - else - uChannel.reset(); + approximator.save(bitOutputStream); - if (vChannel == null) - vChannel = new Channel(width, height); - else - vChannel.reset(); + width = image.metaData.width; + height = image.metaData.height; - // create YUV map out of RGB raster data - final Color color = new Color(); + final WritableRaster raster = image.bufferedImage.getRaster(); + final DataBufferByte dbi = (DataBufferByte) raster.getDataBuffer(); + final byte[] pixels = dbi.getData(); - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) { + if (yChannel == null) + yChannel = new Channel(width, height); + else + yChannel.reset(); - final int index = (y * width) + x; - final int colorBufferIndex = index * 3; + if (uChannel == null) + uChannel = new Channel(width, height); + else + uChannel.reset(); - int blue = pixels[colorBufferIndex]; - if (blue < 0) - blue = blue + 256; + if (vChannel == null) + vChannel = new Channel(width, height); + else + vChannel.reset(); - int green = pixels[colorBufferIndex + 1]; - if (green < 0) - green = green + 256; + // create YUV map out of RGB raster data + final Color color = new Color(); - int red = pixels[colorBufferIndex + 2]; - if (red < 0) - red = red + 256; + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) { - color.r = red; - color.g = green; - color.b = blue; + final int index = (y * width) + x; + final int colorBufferIndex = index * 3; - color.RGB2YUV(); + int blue = pixels[colorBufferIndex]; + if (blue < 0) + blue = blue + 256; - yChannel.map[index] = (byte) color.y; - uChannel.map[index] = (byte) color.u; - vChannel.map[index] = (byte) color.v; - } + int green = pixels[colorBufferIndex + 1]; + if (green < 0) + green = green + 256; - yChannel.decodedMap[0] = yChannel.map[0]; - uChannel.decodedMap[0] = uChannel.map[0]; - vChannel.decodedMap[0] = vChannel.map[0]; + int red = pixels[colorBufferIndex + 2]; + if (red < 0) + red = red + 256; - bitOutputStream.storeBits(byteToInt(yChannel.map[0]), 8); - bitOutputStream.storeBits(byteToInt(uChannel.map[0]), 8); - bitOutputStream.storeBits(byteToInt(vChannel.map[0]), 8); + color.r = red; + color.g = green; + color.b = blue; - // detect initial step - int largestDimension; - int initialStep = 2; - if (width > height) - largestDimension = width; - else - largestDimension = height; + color.RGB2YUV(); - while (initialStep < largestDimension) - initialStep = initialStep * 2; + yChannel.map[index] = (byte) color.y; + uChannel.map[index] = (byte) color.u; + vChannel.map[index] = (byte) color.v; + } - rangeGrid(initialStep); - rangeRoundGrid(2); - saveGrid(initialStep); - } + yChannel.decodedMap[0] = yChannel.map[0]; + uChannel.decodedMap[0] = uChannel.map[0]; + vChannel.decodedMap[0] = vChannel.map[0]; - private void encodeChannel(final Table table, final Channel channel, - final int averageDecodedValue, final int index, final int value, - final int range, final int parentIndex) throws IOException { + bitOutputStream.storeBits(byteToInt(yChannel.map[0]), 8); + bitOutputStream.storeBits(byteToInt(uChannel.map[0]), 8); + bitOutputStream.storeBits(byteToInt(vChannel.map[0]), 8); - final byte[] decodedRangeMap = channel.decodedRangeMap; - final byte[] decodedMap = channel.decodedMap; + // detect initial step + int largestDimension; + int initialStep = 2; + if (width > height) + largestDimension = width; + else + largestDimension = height; - final int inheritedRange = byteToInt(decodedRangeMap[parentIndex]); + while (initialStep < largestDimension) + initialStep = initialStep * 2; - final int inheritedBitCount = table - .proposeBitcountForRange(inheritedRange); + rangeGrid(initialStep); + rangeRoundGrid(2); + saveGrid(initialStep); + } + + private void encodeChannel(final Table table, final Channel channel, + final int averageDecodedValue, final int index, final int value, + final int range, final int parentIndex) throws IOException { + + final byte[] decodedRangeMap = channel.decodedRangeMap; + final byte[] decodedMap = channel.decodedMap; + + final int inheritedRange = byteToInt(decodedRangeMap[parentIndex]); + + final int inheritedBitCount = table + .proposeBitcountForRange(inheritedRange); - if (inheritedBitCount > 0) { - int computedRange; - computedRange = table.proposeRangeForRange(range, inheritedRange); - decodedRangeMap[index] = (byte) computedRange; + if (inheritedBitCount > 0) { + int computedRange; + computedRange = table.proposeRangeForRange(range, inheritedRange); + decodedRangeMap[index] = (byte) computedRange; - channel.bitCount++; - if (computedRange != inheritedRange) - // brightness range shrinked - bitOutputStream.storeBits(1, 1); - else - // brightness range stayed the same - bitOutputStream.storeBits(0, 1); - - // encode brightness into available amount of bits - final int computedBitCount = table - .proposeBitcountForRange(computedRange); - - if (computedBitCount > 0) { - - final int differenceToEncode = -(value - averageDecodedValue); - final int bitEncodedDifference = encodeValueIntoGivenBits( - differenceToEncode, computedRange, computedBitCount); - - channel.bitCount = channel.bitCount + computedBitCount; - bitOutputStream.storeBits(bitEncodedDifference, - computedBitCount); + channel.bitCount++; + if (computedRange != inheritedRange) + // brightness range shrinked + bitOutputStream.storeBits(1, 1); + else + // brightness range stayed the same + bitOutputStream.storeBits(0, 1); + + // encode brightness into available amount of bits + final int computedBitCount = table + .proposeBitcountForRange(computedRange); + + if (computedBitCount > 0) { + + final int differenceToEncode = -(value - averageDecodedValue); + final int bitEncodedDifference = encodeValueIntoGivenBits( + differenceToEncode, computedRange, computedBitCount); + + channel.bitCount = channel.bitCount + computedBitCount; + bitOutputStream.storeBits(bitEncodedDifference, + computedBitCount); - final int decodedDifference = decodeValueFromGivenBits( - bitEncodedDifference, computedRange, computedBitCount); - int decodedValue = averageDecodedValue - decodedDifference; - if (decodedValue > 255) - decodedValue = 255; - if (decodedValue < 0) - decodedValue = 0; + final int decodedDifference = decodeValueFromGivenBits( + bitEncodedDifference, computedRange, computedBitCount); + int decodedValue = averageDecodedValue - decodedDifference; + if (decodedValue > 255) + decodedValue = 255; + if (decodedValue < 0) + decodedValue = 0; - decodedMap[index] = (byte) decodedValue; - } else - decodedMap[index] = (byte) averageDecodedValue; + decodedMap[index] = (byte) decodedValue; + } else + decodedMap[index] = (byte) averageDecodedValue; - } else { - decodedRangeMap[index] = (byte) inheritedRange; - decodedMap[index] = (byte) averageDecodedValue; - } - } + } else { + decodedRangeMap[index] = (byte) inheritedRange; + decodedMap[index] = (byte) averageDecodedValue; + } + } - public void printStatistics() { - System.out.println("Y channel:"); - yChannel.printStatistics(); + public void printStatistics() { + System.out.println("Y channel:"); + yChannel.printStatistics(); - System.out.println("U channel:"); - uChannel.printStatistics(); + System.out.println("U channel:"); + uChannel.printStatistics(); - System.out.println("V channel:"); - vChannel.printStatistics(); - } + System.out.println("V channel:"); + vChannel.printStatistics(); + } - public void rangeGrid(final int step) { + private void rangeGrid(final int step) { - // gridSquare(step / 2, step / 2, step, pixels); - - rangeGridDiagonal(step / 2, step / 2, step); - rangeGridSquare(step / 2, 0, step); - rangeGridSquare(0, step / 2, step); + // gridSquare(step / 2, step / 2, step, pixels); + + rangeGridDiagonal(step / 2, step / 2, step); + rangeGridSquare(step / 2, 0, step); + rangeGridSquare(0, step / 2, step); - if (step > 2) - rangeGrid(step / 2); - } + if (step > 2) + rangeGrid(step / 2); + } - public void rangeGridDiagonal(final int offsetX, final int offsetY, - final int step) { - for (int y = offsetY; y < height; y = y + step) - for (int x = offsetX; x < width; x = x + step) { + private void rangeGridDiagonal(final int offsetX, final int offsetY, + final int step) { + for (int y = offsetY; y < height; y = y + step) + for (int x = offsetX; x < width; x = x + step) { - final int index = (y * width) + x; - final int halfStep = step / 2; + final int index = (y * width) + x; + final int halfStep = step / 2; - context.initialize(image, yChannel.map, uChannel.map, - vChannel.map); + context.initialize(image, yChannel.map, uChannel.map, + vChannel.map); - context.measureNeighborEncode(x - halfStep, y - halfStep); - context.measureNeighborEncode(x + halfStep, y - halfStep); - context.measureNeighborEncode(x - halfStep, y + halfStep); - context.measureNeighborEncode(x + halfStep, y + halfStep); + context.measureNeighborEncode(x - halfStep, y - halfStep); + context.measureNeighborEncode(x + halfStep, y - halfStep); + context.measureNeighborEncode(x - halfStep, y + halfStep); + context.measureNeighborEncode(x + halfStep, y + halfStep); - yChannel.rangeMap[index] = (byte) context.getYRange(index); - uChannel.rangeMap[index] = (byte) context.getURange(index); - vChannel.rangeMap[index] = (byte) context.getVRange(index); - } - } + yChannel.rangeMap[index] = (byte) context.getYRange(index); + uChannel.rangeMap[index] = (byte) context.getURange(index); + vChannel.rangeMap[index] = (byte) context.getVRange(index); + } + } - public void rangeGridSquare(final int offsetX, final int offsetY, - final int step) { - for (int y = offsetY; y < height; y = y + step) - for (int x = offsetX; x < width; x = x + step) { + private void rangeGridSquare(final int offsetX, final int offsetY, + final int step) { + for (int y = offsetY; y < height; y = y + step) + for (int x = offsetX; x < width; x = x + step) { - final int index = (y * width) + x; - final int halfStep = step / 2; + final int index = (y * width) + x; + final int halfStep = step / 2; - context.initialize(image, yChannel.map, uChannel.map, - vChannel.map); + context.initialize(image, yChannel.map, uChannel.map, + vChannel.map); - context.measureNeighborEncode(x - halfStep, y); - context.measureNeighborEncode(x + halfStep, y); - context.measureNeighborEncode(x, y - halfStep); - context.measureNeighborEncode(x, y + halfStep); + context.measureNeighborEncode(x - halfStep, y); + context.measureNeighborEncode(x + halfStep, y); + context.measureNeighborEncode(x, y - halfStep); + context.measureNeighborEncode(x, y + halfStep); - yChannel.rangeMap[index] = (byte) context.getYRange(index); - uChannel.rangeMap[index] = (byte) context.getURange(index); - vChannel.rangeMap[index] = (byte) context.getVRange(index); - } - } + yChannel.rangeMap[index] = (byte) context.getYRange(index); + uChannel.rangeMap[index] = (byte) context.getURange(index); + vChannel.rangeMap[index] = (byte) context.getVRange(index); + } + } - public void rangeRoundGrid(final int step) { + private void rangeRoundGrid(final int step) { - rangeRoundGridDiagonal(step / 2, step / 2, step); - rangeRoundGridSquare(step / 2, 0, step); - rangeRoundGridSquare(0, step / 2, step); + rangeRoundGridDiagonal(step / 2, step / 2, step); + rangeRoundGridSquare(step / 2, 0, step); + rangeRoundGridSquare(0, step / 2, step); - if (step < 1024) - rangeRoundGrid(step * 2); - } + if (step < 1024) + rangeRoundGrid(step * 2); + } - public void rangeRoundGridDiagonal(final int offsetX, final int offsetY, - final int step) { - for (int y = offsetY; y < height; y = y + step) - for (int x = offsetX; x < width; x = x + step) { + private void rangeRoundGridDiagonal(final int offsetX, final int offsetY, + final int step) { + for (int y = offsetY; y < height; y = y + step) + for (int x = offsetX; x < width; x = x + step) { - final int index = (y * width) + x; + final int index = (y * width) + x; - final int yRange = byteToInt(yChannel.rangeMap[index]); - final int uRange = byteToInt(uChannel.rangeMap[index]); - final int vRange = byteToInt(vChannel.rangeMap[index]); + final int yRange = byteToInt(yChannel.rangeMap[index]); + final int uRange = byteToInt(uChannel.rangeMap[index]); + final int vRange = byteToInt(vChannel.rangeMap[index]); - final int halfStep = step / 2; + final int halfStep = step / 2; - final int parentIndex = ((y - halfStep) * width) - + (x - halfStep); + final int parentIndex = ((y - halfStep) * width) + + (x - halfStep); - int parentYRange = byteToInt(yChannel.rangeMap[parentIndex]); + int parentYRange = byteToInt(yChannel.rangeMap[parentIndex]); - if (parentYRange < yRange) { - parentYRange = yRange; - yChannel.rangeMap[parentIndex] = (byte) parentYRange; - } + if (parentYRange < yRange) { + parentYRange = yRange; + yChannel.rangeMap[parentIndex] = (byte) parentYRange; + } - int parentURange = byteToInt(uChannel.rangeMap[parentIndex]); + int parentURange = byteToInt(uChannel.rangeMap[parentIndex]); - if (parentURange < uRange) { - parentURange = uRange; - uChannel.rangeMap[parentIndex] = (byte) parentURange; - } + if (parentURange < uRange) { + parentURange = uRange; + uChannel.rangeMap[parentIndex] = (byte) parentURange; + } - int parentVRange = byteToInt(vChannel.rangeMap[parentIndex]); + int parentVRange = byteToInt(vChannel.rangeMap[parentIndex]); - if (parentVRange < vRange) { - parentVRange = vRange; - vChannel.rangeMap[parentIndex] = (byte) parentVRange; - } - } - } + if (parentVRange < vRange) { + parentVRange = vRange; + vChannel.rangeMap[parentIndex] = (byte) parentVRange; + } + } + } - public void rangeRoundGridSquare(final int offsetX, final int offsetY, - final int step) { - for (int y = offsetY; y < height; y = y + step) - for (int x = offsetX; x < width; x = x + step) { + private void rangeRoundGridSquare(final int offsetX, final int offsetY, + final int step) { + for (int y = offsetY; y < height; y = y + step) + for (int x = offsetX; x < width; x = x + step) { - final int index = (y * width) + x; + final int index = (y * width) + x; - final int yRange = byteToInt(yChannel.rangeMap[index]); - final int uRange = byteToInt(uChannel.rangeMap[index]); - final int vRange = byteToInt(vChannel.rangeMap[index]); + final int yRange = byteToInt(yChannel.rangeMap[index]); + final int uRange = byteToInt(uChannel.rangeMap[index]); + final int vRange = byteToInt(vChannel.rangeMap[index]); - final int halfStep = step / 2; + final int halfStep = step / 2; - int parentIndex; - if (offsetX > 0) - parentIndex = (y * width) + (x - halfStep); - else - parentIndex = ((y - halfStep) * width) + x; + int parentIndex; + if (offsetX > 0) + parentIndex = (y * width) + (x - halfStep); + else + parentIndex = ((y - halfStep) * width) + x; - int parentYRange = byteToInt(yChannel.rangeMap[parentIndex]); + int parentYRange = byteToInt(yChannel.rangeMap[parentIndex]); - if (parentYRange < yRange) { - parentYRange = yRange; - yChannel.rangeMap[parentIndex] = (byte) parentYRange; - } + if (parentYRange < yRange) { + parentYRange = yRange; + yChannel.rangeMap[parentIndex] = (byte) parentYRange; + } - int parentURange = byteToInt(uChannel.rangeMap[parentIndex]); + int parentURange = byteToInt(uChannel.rangeMap[parentIndex]); - if (parentURange < uRange) { - parentURange = uRange; - uChannel.rangeMap[parentIndex] = (byte) parentURange; - } + if (parentURange < uRange) { + parentURange = uRange; + uChannel.rangeMap[parentIndex] = (byte) parentURange; + } - int parentVRange = byteToInt(vChannel.rangeMap[parentIndex]); + int parentVRange = byteToInt(vChannel.rangeMap[parentIndex]); - if (parentVRange < vRange) { - parentVRange = vRange; - vChannel.rangeMap[parentIndex] = (byte) parentVRange; - } + if (parentVRange < vRange) { + parentVRange = vRange; + vChannel.rangeMap[parentIndex] = (byte) parentVRange; + } - } - } + } + } - public void saveGrid(final int step) throws IOException { + private void saveGrid(final int step) throws IOException { - saveGridDiagonal(step / 2, step / 2, step); - saveGridSquare(step / 2, 0, step); - saveGridSquare(0, step / 2, step); + saveGridDiagonal(step / 2, step / 2, step); + saveGridSquare(step / 2, 0, step); + saveGridSquare(0, step / 2, step); - if (step > 2) - saveGrid(step / 2); - } + if (step > 2) + saveGrid(step / 2); + } - public void saveGridDiagonal(final int offsetX, final int offsetY, - final int step) throws IOException { - for (int y = offsetY; y < height; y = y + step) - for (int x = offsetX; x < width; x = x + step) { + private void saveGridDiagonal(final int offsetX, final int offsetY, + final int step) throws IOException { + for (int y = offsetY; y < height; y = y + step) + for (int x = offsetX; x < width; x = x + step) { - final int halfStep = step / 2; + final int halfStep = step / 2; - context2.initialize(image, yChannel.decodedMap, - uChannel.decodedMap, vChannel.decodedMap); - context2.measureNeighborEncode(x - halfStep, y - halfStep); - context2.measureNeighborEncode(x + halfStep, y - halfStep); - context2.measureNeighborEncode(x - halfStep, y + halfStep); - context2.measureNeighborEncode(x + halfStep, y + halfStep); + context2.initialize(image, yChannel.decodedMap, + uChannel.decodedMap, vChannel.decodedMap); + context2.measureNeighborEncode(x - halfStep, y - halfStep); + context2.measureNeighborEncode(x + halfStep, y - halfStep); + context2.measureNeighborEncode(x - halfStep, y + halfStep); + context2.measureNeighborEncode(x + halfStep, y + halfStep); - savePixel(step, offsetX, offsetY, x, y, - context2.colorStats.getAverageY(), - context2.colorStats.getAverageU(), - context2.colorStats.getAverageV()); + savePixel(step, offsetX, offsetY, x, y, + context2.colorStats.getAverageY(), + context2.colorStats.getAverageU(), + context2.colorStats.getAverageV()); - } - } + } + } - public void saveGridSquare(final int offsetX, final int offsetY, - final int step) throws IOException { - for (int y = offsetY; y < height; y = y + step) - for (int x = offsetX; x < width; x = x + step) { + private void saveGridSquare(final int offsetX, final int offsetY, + final int step) throws IOException { + for (int y = offsetY; y < height; y = y + step) + for (int x = offsetX; x < width; x = x + step) { - final int halfStep = step / 2; + final int halfStep = step / 2; - context2.initialize(image, yChannel.decodedMap, - uChannel.decodedMap, vChannel.decodedMap); - context2.measureNeighborEncode(x - halfStep, y); - context2.measureNeighborEncode(x + halfStep, y); - context2.measureNeighborEncode(x, y - halfStep); - context2.measureNeighborEncode(x, y + halfStep); + context2.initialize(image, yChannel.decodedMap, + uChannel.decodedMap, vChannel.decodedMap); + context2.measureNeighborEncode(x - halfStep, y); + context2.measureNeighborEncode(x + halfStep, y); + context2.measureNeighborEncode(x, y - halfStep); + context2.measureNeighborEncode(x, y + halfStep); - savePixel(step, offsetX, offsetY, x, y, - context2.colorStats.getAverageY(), - context2.colorStats.getAverageU(), - context2.colorStats.getAverageV()); + savePixel(step, offsetX, offsetY, x, y, + context2.colorStats.getAverageY(), + context2.colorStats.getAverageU(), + context2.colorStats.getAverageV()); - } - } + } + } - public void savePixel(final int step, final int offsetX, final int offsetY, - final int x, final int y, final int averageDecodedY, - final int averageDecodedU, final int averageDecodedV) - throws IOException { + private void savePixel(final int step, final int offsetX, final int offsetY, + final int x, final int y, final int averageDecodedY, + final int averageDecodedU, final int averageDecodedV) + throws IOException { - final int index = (y * width) + x; + final int index = (y * width) + x; - final int py = byteToInt(yChannel.map[index]); - final int pu = byteToInt(uChannel.map[index]); - final int pv = byteToInt(vChannel.map[index]); + final int py = byteToInt(yChannel.map[index]); + final int pu = byteToInt(uChannel.map[index]); + final int pv = byteToInt(vChannel.map[index]); - final int yRange = byteToInt(yChannel.rangeMap[index]); - final int uRange = byteToInt(uChannel.rangeMap[index]); - final int vRange = byteToInt(vChannel.rangeMap[index]); + final int yRange = byteToInt(yChannel.rangeMap[index]); + final int uRange = byteToInt(uChannel.rangeMap[index]); + final int vRange = byteToInt(vChannel.rangeMap[index]); - final int halfStep = step / 2; + final int halfStep = step / 2; - int parentIndex; - if (offsetX > 0) { - if (offsetY > 0) - // diagonal approach - parentIndex = ((y - halfStep) * width) + (x - halfStep); - else - // take left pixel - parentIndex = (y * width) + (x - halfStep); - } else - // take upper pixel - parentIndex = ((y - halfStep) * width) + x; + int parentIndex; + if (offsetX > 0) { + if (offsetY > 0) + // diagonal approach + parentIndex = ((y - halfStep) * width) + (x - halfStep); + else + // take left pixel + parentIndex = (y * width) + (x - halfStep); + } else + // take upper pixel + parentIndex = ((y - halfStep) * width) + x; - encodeChannel(approximator.yTable, yChannel, averageDecodedY, index, - py, yRange, parentIndex); - - encodeChannel(approximator.uTable, uChannel, averageDecodedU, index, - pu, uRange, parentIndex); + encodeChannel(approximator.yTable, yChannel, averageDecodedY, index, + py, yRange, parentIndex); + + encodeChannel(approximator.uTable, uChannel, averageDecodedU, index, + pu, uRange, parentIndex); - encodeChannel(approximator.vTable, vChannel, averageDecodedV, index, - pv, vRange, parentIndex); + encodeChannel(approximator.vTable, vChannel, averageDecodedV, index, + pv, vRange, parentIndex); - } + } }