diff options
author | Sven Gothel <[email protected]> | 2012-04-07 15:28:37 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-04-07 15:28:37 +0200 |
commit | 40830196070013432bc5f453eb31cfe4c64e0510 (patch) | |
tree | ca31a1e1e27adf9996963176c4f92b84e25623e9 /src/jogl/classes/jogamp/opengl/util/pngj/ImageLine.java | |
parent | 865c0588de57c9a020a435bc3f08be0f3f6ba162 (diff) |
Merge PNGJ 0.85 into namespace
PNGJ Version 0.85 (1 April 2012)
Apache 2.0 License
http://code.google.com/p/pngj/
Merged code:
- Changed namespace ar.com.hjg.pngj -> jogamp.opengl.util.pngj
to avoid collision when using a different version of PNGJ.
- Removed test and lossy packages and helper classes
to reduce footprint.
License information is added in main LICENSE.txt file.
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/util/pngj/ImageLine.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/util/pngj/ImageLine.java | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/jogl/classes/jogamp/opengl/util/pngj/ImageLine.java b/src/jogl/classes/jogamp/opengl/util/pngj/ImageLine.java new file mode 100644 index 000000000..bfbb35b7c --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/util/pngj/ImageLine.java @@ -0,0 +1,175 @@ +package jogamp.opengl.util.pngj;
+
+import java.util.Arrays;
+
+/**
+ * Lightweight wrapper for an image scanline, used for read and write.
+ * <p>
+ * This object can be (usually it is) reused while iterating over the image lines.
+ * <p>
+ * See <code>scanline</code> field, to understand the format.
+ */
+public class ImageLine {
+ public final ImageInfo imgInfo;
+
+ /**
+ * tracks the current row number (from 0 to rows-1)
+ */
+ private int rown = 0;
+
+ /**
+ * The 'scanline' is an array of integers, corresponds to an image line (row).
+ * <p>
+ * Except for 'packed' formats (gray/indexed with 1-2-4 bitdepth) each int is a "sample" (one for channel), (0-255
+ * or 0-65535) in the respective PNG sequence sequence : (R G B R G B...) or (R G B A R G B A...) or (g g g ...) or
+ * ( i i i) (palette index)
+ * <p>
+ * For bitdepth 1/2/4 , each element is a PACKED byte! To get an unpacked copy, see <code>tf_pack()</code> and its
+ * inverse <code>tf_unpack()</code>
+ * <p>
+ * To convert a indexed line to RGB balues, see <code>ImageLineHelper.tf_palIdx2RGB()</code> (can't do the reverse)
+ */
+ public final int[] scanline; // see explanation above!!
+
+ protected FilterType filterUsed; // informational ; only filled by the reader
+ public final int channels; // copied from imgInfo, more handy
+ public final int bitDepth; // copied from imgInfo, more handy
+
+ public ImageLine(ImageInfo imgInfo) {
+ this.imgInfo = imgInfo;
+ channels = imgInfo.channels;
+ scanline = new int[imgInfo.samplesPerRowP];
+ this.bitDepth = imgInfo.bitDepth;
+ }
+
+ /** This row number inside the image (0 is top) */
+ public int getRown() {
+ return rown;
+ }
+
+ /** Increments row number */
+ public void incRown() {
+ this.rown++;
+ }
+
+ /** Sets row number */
+ public void setRown(int n) {
+ this.rown = n;
+ }
+
+ /** Sets scanline, making copy from passed array */
+ public void setScanLine(int[] b) {
+ System.arraycopy(b, 0, scanline, 0, scanline.length);
+ }
+
+ /**
+ * Returns a copy from scanline, in byte array.
+ *
+ * You can (OPTIONALLY) pass an preallocated array to use.
+ **/
+ public int[] getScanLineCopy(int[] b) {
+ if (b == null || b.length < scanline.length)
+ b = new int[scanline.length];
+ System.arraycopy(scanline, 0, b, 0, scanline.length);
+ return b;
+ }
+
+ /**
+ * Unpacks scanline (for bitdepth 1-2-4) into buffer.
+ * <p>
+ * You can (OPTIONALLY) pass an preallocated array to use.
+ * <p>
+ * If scale==TRUE scales the value (just a bit shift).
+ */
+ public int[] tf_unpack(int[] buf, boolean scale) {
+ int len = scanline.length;
+ if (bitDepth == 1)
+ len *= 8;
+ else if (bitDepth == 2)
+ len *= 4;
+ else if (bitDepth == 4)
+ len *= 2;
+ if (buf == null)
+ buf = new int[len];
+ if (bitDepth >= 8)
+ System.arraycopy(scanline, 0, buf, 0, scanline.length);
+ else {
+ int mask, offset, v;
+ int mask0 = getMaskForPackedFormats();
+ int offset0 = 8 - bitDepth;
+ mask = mask0;
+ offset = offset0;
+ for (int i = 0, j = 0; i < len; i++) {
+ v = (scanline[j] & mask) >> offset;
+ if (scale)
+ v <<= offset0;
+ buf[i] = v;
+ mask = mask >> bitDepth;
+ offset -= bitDepth;
+ if (mask == 0) { // new byte in source
+ mask = mask0;
+ offset = offset0;
+ j++;
+ }
+ }
+ }
+ return buf;
+ }
+
+ /**
+ * Packs scanline (for bitdepth 1-2-4) from buffer.
+ * <p>
+ * If scale==TRUE scales the value (just a bit shift).
+ */
+ public void tf_pack(int[] buf, boolean scale) { // writes scanline
+ int len = scanline.length;
+ if (bitDepth == 1)
+ len *= 8;
+ else if (bitDepth == 2)
+ len *= 4;
+ else if (bitDepth == 4)
+ len *= 2;
+ if (bitDepth >= 8)
+ System.arraycopy(buf, 0, scanline, 0, scanline.length);
+ else {
+ int offset0 = 8 - bitDepth;
+ int mask0 = getMaskForPackedFormats() >> offset0;
+ int offset, v;
+ offset = offset0;
+ Arrays.fill(scanline, 0);
+ for (int i = 0, j = 0; i < len; i++) {
+ v = buf[i];
+ if (scale)
+ v >>= offset0;
+ v = (v & mask0) << offset;
+ scanline[j] |= v;
+ offset -= bitDepth;
+ if (offset < 0) { // new byte in scanline
+ offset = offset0;
+ j++;
+ }
+ }
+ }
+ }
+
+ private int getMaskForPackedFormats() { // Utility function for pacj/unpack
+ if (bitDepth == 1)
+ return 0x80;
+ if (bitDepth == 2)
+ return 0xc0;
+ if (bitDepth == 4)
+ return 0xf0;
+ throw new RuntimeException("?");
+ }
+
+ public FilterType getFilterUsed() {
+ return filterUsed;
+ }
+
+ /**
+ * Basic info
+ */
+ public String toString() {
+ return "row=" + rown + " cols=" + imgInfo.cols + " bpc=" + imgInfo.bitDepth + " size=" + scanline.length;
+ }
+}
|