aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/glu/mipmap/HalveImage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/glu/mipmap/HalveImage.java')
-rw-r--r--src/jogl/classes/jogamp/opengl/glu/mipmap/HalveImage.java1533
1 files changed, 1533 insertions, 0 deletions
diff --git a/src/jogl/classes/jogamp/opengl/glu/mipmap/HalveImage.java b/src/jogl/classes/jogamp/opengl/glu/mipmap/HalveImage.java
new file mode 100644
index 000000000..893d33c66
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/glu/mipmap/HalveImage.java
@@ -0,0 +1,1533 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import javax.media.opengl.GL;
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class HalveImage {
+
+ private static final int BOX2 = 2;
+ private static final int BOX4 = 4;
+ private static final int BOX8 = 8;
+
+ public static void halveImage( int components, int width, int height,
+ ShortBuffer datain, ShortBuffer dataout ) {
+ int i, j, k;
+ int newwidth, newheight;
+ int delta;
+ int t = 0;
+ short temp = 0;
+
+ newwidth = width / 2;
+ newheight = height /2;
+ delta = width * components;
+
+ // Piece of cake
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.get();
+ datain.position( t + components );
+ temp += datain.get();
+ datain.position( t + delta );
+ temp += datain.get();
+ datain.position( t + delta + components );
+ temp +=datain.get();
+ temp += 2;
+ temp /= 4;
+ dataout.put( temp );
+ t++;
+ }
+ t += components;
+ }
+ t += delta;
+ }
+ }
+
+ public static void halveImage_ubyte( int components, int width, int height,
+ ByteBuffer datain, ByteBuffer dataout,
+ int element_size, int ysize, int group_size ) {
+ int i, j, k;
+ int newwidth, newheight;
+ int s;
+ int t;
+
+ // Handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_ubyte( components, width, height, datain, dataout, element_size, ysize, group_size );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+ s = 0;
+ t = 0;
+
+ int temp = 0;
+ // piece of cake
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = ( 0x000000FF & datain.get() );
+ datain.position( t + group_size );
+ temp += ( 0x000000FF & datain.get() );
+ datain.position( t + ysize );
+ temp += ( 0x000000FF & datain.get() );
+ datain.position( t + ysize + group_size );
+ temp += ( 0x000000FF & datain.get() ) + 2;
+ dataout.put( (byte)(temp / 4) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+
+ public static void halve1Dimage_ubyte( int components, int width, int height,
+ ByteBuffer datain, ByteBuffer dataout,
+ int element_size, int ysize, int group_size ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+ int temp = 0;
+
+ assert( width == 1 || height == 1 ); // Must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // widthxheight can't be 1x1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ datain.position( src );
+ temp = ( 0x000000FF & datain.get() );
+ datain.position( src + group_size );
+ temp += ( 0x000000FF & datain.get() );
+ temp /= 2;
+ dataout.put( (byte)temp );
+ /*
+ dataout.setByte( (byte)(((0x000000FF & datain.setIndexInBytes(src).getByte()) +
+ (0x000000FF & datain.setIndexInBytes( src + group_size ).getByte())) / 2 ) );
+ */
+ src += element_size;
+ //dataout.plusPlus();
+ dest++;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) { // 1 column
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ datain.position( src );
+ temp = ( 0x000000FF & datain.get() );
+ datain.position( src + ysize );
+ temp += ( 0x000000FF & datain.get() );
+ temp /= 2;
+ dataout.put( (byte)temp );
+ /*
+ dataout.setByte( (byte)(((0x000000FF & datain.setIndexInBytes(src).getByte()) +
+ (0x000000FF & datain.setIndexInBytes(src + ysize).getByte()) ) / 2 ) );
+ */
+ src += element_size;
+ //dataout.plusPlus();
+ dest++;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ }
+ assert( src == ysize * height );
+ assert( dest == components * element_size * halfWidth * halfHeight );
+ }
+
+ public static void halveImage_byte( int components, int width, int height,
+ ByteBuffer datain, ByteBuffer dataout, int element_size,
+ int ysize, int group_size ) {
+ int i, j, k;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ byte temp = (byte)0;
+
+ // handle case where there is only 1 column
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) );
+ halve1Dimage_byte( components, width, height, datain, dataout, element_size,
+ ysize, group_size );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.get();
+ datain.position( t + group_size );
+ temp += datain.get();
+ datain.position( t + ysize );
+ temp += datain.get();
+ datain.position( t + ysize + group_size );
+ temp += datain.get();
+ temp += 2;
+ temp /= 4;
+ dataout.put( temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+
+ public static void halve1Dimage_byte( int components, int width, int height,
+ ByteBuffer datain, ByteBuffer dataout,
+ int element_size, int ysize, int group_size ) {
+ int halfWidth = width / 2;
+ int halfHeight = width / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+ byte temp = (byte)0;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // widthxheight can't be 1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ datain.position( src );
+ temp = datain.get();
+ datain.position( src + group_size );
+ temp += datain.get();
+ temp /= 2;
+ dataout.put( temp );
+ src += element_size;
+ dest++;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assert only
+ } else if( width == 1 ) { // 1 column
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 ); // widthxheight can't be 1
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ datain.position( src );
+ temp = datain.get();
+ datain.position( src + ysize );
+ temp += datain.get();
+ temp /= 2;
+ src += element_size;
+ dest++;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == components * element_size * halfWidth * halfHeight );
+ }
+
+ public static void halveImage_ushort( int components, int width, int height,
+ ByteBuffer datain, ShortBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ int temp = 0;
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_ushort( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = ( 0x0000FFFF & datain.getShort() );
+ datain.position( t + group_size );
+ temp += ( 0x0000FFFF & datain.getShort() );
+ datain.position( t + ysize );
+ temp += ( 0x0000FFFF & datain.getShort() );
+ datain.position( t + ysize + group_size );
+ temp += ( 0x0000FFFF & datain.getShort() );
+ dataout.put( (short)( ( temp + 2 ) / 4 ) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( t + group_size );
+ temp += ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( t + ysize );
+ temp += ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( t + ysize + group_size );
+ temp += ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ dataout.put( (short)( ( temp + 2 ) / 4 ) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_ushort( int components, int width, int height,
+ ByteBuffer datain, ShortBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // widthxheight can't be 1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < halfHeight; kk++ ) {
+ int[] ushort = new int[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ ushort[0] = ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( src + group_size );
+ ushort[1] = (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ } else {
+ datain.position( src );
+ ushort[0] = (0x0000FFFF & datain.getShort() );
+ datain.position( src + group_size );
+ ushort[1] = (0x0000FFFF & datain.getShort() );
+ }
+ dataout.put( (short)( (ushort[0] + ushort[1]) / 2 ) );
+ src += element_size;
+ dest += 2;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) { // 1 column
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 ); // widthxheight can't be 1
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ int[] ushort = new int[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ ushort[0] = ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( src + ysize );
+ ushort[0] = ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ } else {
+ datain.position( src );
+ ushort[0] = ( 0x0000FFFF & datain.getShort() );
+ datain.position( src + ysize );
+ ushort[1] = ( 0x0000FFFF & datain.getShort() );
+ }
+ dataout.put( (short)((ushort[0] + ushort[1]) / 2) );
+ src += element_size;
+ dest += 2;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == components * element_size * halfWidth * halfHeight );
+ }
+
+ public static void halveImage_short( int components, int width, int height,
+ ByteBuffer datain, ShortBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ short temp = (short)0;
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_short( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.getShort();
+ datain.position( t + group_size );
+ temp += datain.getShort();
+ datain.position( t + ysize );
+ temp += datain.getShort();
+ datain.position( t + ysize + group_size );
+ temp += datain.getShort();
+ temp += 2;
+ temp /= 4;
+ dataout.put( (short)temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ short b;
+ int buf;
+ datain.position( t );
+ temp = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( t + group_size );
+ temp += Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( t + ysize );
+ temp += Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( t + ysize + group_size );
+ temp += Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ temp += 2;
+ temp /= 4;
+ dataout.put( temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_short( int components, int width, int height,
+ ByteBuffer datain, ShortBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // can't be 1x1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ short[] sshort = new short[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ sshort[0] = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( src + group_size );
+ sshort[1] = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ } else {
+ datain.position( src );
+ sshort[0] = datain.getShort();
+ datain.position( src + group_size );
+ sshort[1] = datain.getShort();
+ }
+ dataout.put( (short)(( sshort[0] + sshort[1] ) / 2) );
+ src += element_size;
+ dest += 2;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) {
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ short[] sshort = new short[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ sshort[0] = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( src + ysize );
+ sshort[1] = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ } else {
+ datain.position( src );
+ sshort[0] = datain.getShort();
+ datain.position( src + ysize );
+ sshort[1] = datain.getShort();
+ }
+ dataout.put( (short)(( sshort[0] + sshort[1] ) / 2) );
+ src += element_size;
+ dest += 2;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == ( components * element_size * halfWidth * halfHeight ) );
+ }
+
+ public static void halveImage_uint( int components, int width, int height,
+ ByteBuffer datain, IntBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ double temp = 0;
+
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_uint( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = (0x000000007FFFFFFFL & datain.getInt() );
+ datain.position( t + group_size );
+ temp += (0x000000007FFFFFFFL & datain.getInt() );
+ datain.position( t + ysize );
+ temp += (0x000000007FFFFFFFL & datain.getInt() );
+ datain.position( t + ysize + group_size );
+ temp += (0x000000007FFFFFFFL & datain.getInt() );
+ dataout.put( (int)( ( temp / 4 ) + 0.5 ) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ // need to cast to double to hold large unsigned ints
+ double buf;
+ datain.position( t );
+ buf = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( t + group_size );
+ buf += ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( t + ysize );
+ buf += ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( t + ysize + group_size );
+ buf += ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ temp /= 4;
+ temp += 0.5;
+ dataout.put( (int)temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_uint( int components, int width, int height,
+ ByteBuffer datain, IntBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // widthxheight can't be 1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < halfHeight; kk++ ) {
+ long[] uint = new long[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( src + group_size );
+ uint[1] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ } else {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ datain.position( src + group_size );
+ uint[1] = (0x00000000FFFFFFFF & datain.getInt() );
+ }
+ dataout.put( (int)( ( uint[0] + uint[1] ) / 2.0 ) );
+ src += element_size;
+ dest += 4;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) { // 1 column
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 ); // widthxheight can't be 1
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ long[] uint = new long[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( src + group_size );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ } else {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ datain.position( src + ysize );
+ uint[1] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ }
+ dataout.put( (int)( ( uint[0] + uint[1] ) / 2.0 ) );
+ src += element_size;
+ dest += 4;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == components * element_size * halfWidth * halfHeight );
+ }
+
+ public static void halveImage_int( int components, int width, int height,
+ ByteBuffer datain, IntBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ int temp = 0;
+
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_int( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.getInt();
+ datain.position( t + group_size );
+ temp += datain.getInt();
+ datain.position( t + ysize );
+ temp += datain.getInt();
+ datain.position( t + ysize + group_size );
+ temp += datain.getInt();
+ temp = (int)( ( temp / 4.0f ) + 0.5f );
+ dataout.put( temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ long b;
+ float buf;
+ datain.position( t );
+ b = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ buf = b;
+ datain.position( t + group_size );
+ b = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ buf += b;
+ datain.position( t + ysize );
+ b = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ buf += b;
+ datain.position( t + ysize + group_size );
+ b = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ buf += b;
+ dataout.put( (int)( ( buf / 4.0f ) + 0.5f ) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_int( int components, int width, int height,
+ ByteBuffer datain, IntBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // can't be 1x1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ long[] uint = new long[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( src + group_size );
+ uint[1] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ } else {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ datain.position( src + group_size );
+ uint[1] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ }
+ dataout.put( (int)( ( (float)uint[0] + (float)uint[1] ) / 2.0f) );
+ src += element_size;
+ dest += 4;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) {
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ long[] uint = new long[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( src + ysize );
+ uint[1] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ } else {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ datain.position( src + ysize );
+ uint[1] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ }
+ dataout.put( (int)(( (float)uint[0] + (float)uint[1] ) / 2.0f) );
+ src += element_size;
+ dest += 4;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == ( components * element_size * halfWidth * halfHeight ) );
+ }
+
+ public static void halveImage_float( int components, int width, int height,
+ ByteBuffer datain, FloatBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ float temp = 0.0f;
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_float( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.getFloat();
+ datain.position( t + group_size );
+ temp += datain.getFloat();
+ datain.position( t + ysize );
+ temp += datain.getFloat();
+ datain.position( t + ysize + group_size );
+ temp /= 4.0f;
+ dataout.put( temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ float buf;
+ datain.position( t );
+ buf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( t + group_size );
+ buf += Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( t + ysize );
+ buf += Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( t + ysize + group_size );
+ buf += Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ dataout.put( buf / 4.0f );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_float( int components, int width, int height,
+ ByteBuffer datain, FloatBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // can't be 1x1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ float[] sfloat = new float[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ sfloat[0] = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( src + group_size );
+ sfloat[1] = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ } else {
+ datain.position( src );
+ sfloat[0] = datain.getFloat();
+ datain.position( src + group_size );
+ sfloat[1] = datain.getFloat();
+ }
+ dataout.put( (sfloat[0] + sfloat[1]) / 2.0f );
+ src += element_size;
+ dest += 4;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) {
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ float[] sfloat = new float[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ sfloat[0] = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( src + ysize );
+ sfloat[1] = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ } else {
+ datain.position( src );
+ sfloat[0] = datain.getFloat();
+ datain.position( src + ysize );
+ sfloat[1] = datain.getFloat();
+ }
+ dataout.put( ( sfloat[0] + sfloat[1] ) / 2.0f );
+ src += element_size;
+ dest += 4;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == ( components * element_size * halfWidth * halfHeight ) );
+ }
+
+ public static void halveImagePackedPixel( int components, Extract extract, int width,
+ int height, ByteBuffer datain, ByteBuffer dataout,
+ int pixelSizeInBytes, int rowSizeInBytes, boolean isSwap ) {
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) );
+ halve1DimagePackedPixel( components, extract, width, height, datain, dataout,
+ pixelSizeInBytes, rowSizeInBytes, isSwap );
+ return;
+ }
+ int ii, jj;
+
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * pixelSizeInBytes );
+ int outIndex = 0;
+
+ for( ii = 0; ii < halfHeight; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float totals[] = new float[4];
+ float extractTotals[][] = new float[BOX4][4];
+ int cc;
+
+ datain.position( src );
+ extract.extract( isSwap, datain, extractTotals[0] );
+ datain.position( src + pixelSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[1] );
+ datain.position( src + rowSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[2] );
+ datain.position( src + rowSizeInBytes + pixelSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[3] );
+ for( cc = 0; cc < components; cc++ ) {
+ int kk = 0;
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= BOX4;
+ }
+ extract.shove( totals, outIndex, dataout );
+ outIndex++;
+ src += pixelSizeInBytes + pixelSizeInBytes;
+ }
+ // skip past pad bytes, if any, to get to next row
+ src += padBytes;
+ src += rowSizeInBytes;
+ }
+ assert( src == rowSizeInBytes * height );
+ assert( outIndex == halfWidth * halfHeight );
+ }
+
+ public static void halve1DimagePackedPixel( int components, Extract extract, int width,
+ int height, ByteBuffer datain, ByteBuffer dataout,
+ int pixelSizeInBytes, int rowSizeInBytes, boolean isSwap ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 );
+ assert( width != height );
+
+ if( height == 1 ) {
+ int outIndex = 0;
+
+ assert( width != 1 );
+ halfHeight = 1;
+
+ // one horizontal row with possible pad bytes
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float[] totals = new float[4];
+ float[][] extractTotals = new float[BOX2][4];
+ int cc;
+
+ datain.position( src );
+ extract.extract( isSwap, datain, extractTotals[0] );
+ datain.position( src + pixelSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[1] );
+ for( cc = 0; cc < components; cc++ ) {
+ int kk = 0;
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX2; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= BOX2;
+ }
+ extract.shove( totals, outIndex, dataout );
+ outIndex++;
+ // skip over to next group of 2
+ src += pixelSizeInBytes + pixelSizeInBytes;
+ }
+ int padBytes = rowSizeInBytes - ( width * pixelSizeInBytes );
+ src += padBytes;
+
+ assert( src == rowSizeInBytes );
+ assert( outIndex == halfWidth * halfHeight );
+ } else if( width == 1 ) {
+ int outIndex = 0;
+
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical volumn with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ float[] totals = new float[4];
+ float[][] extractTotals = new float[BOX2][4];
+ int cc;
+ // average two at a time, instead of four
+ datain.position( src );
+ extract.extract( isSwap, datain, extractTotals[0] );
+ datain.position( src + rowSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[1] );
+ for( cc = 0; cc < components; cc++ ) {
+ int kk = 0;
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX2; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= BOX2;
+ }
+ extract.shove( totals, outIndex, dataout );
+ outIndex++;
+ // skip over to next group of 2
+ src += rowSizeInBytes + rowSizeInBytes;
+ }
+ assert( src == rowSizeInBytes );
+ assert( outIndex == halfWidth * halfHeight );
+ }
+ }
+
+ public static void halveImagePackedPixelSlice( int components, Extract extract,
+ int width, int height, int depth, ByteBuffer dataIn,
+ ByteBuffer dataOut, int pixelSizeInBytes, int rowSizeInBytes,
+ int imageSizeInBytes, boolean isSwap ) {
+ int ii, jj;
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int halfDepth = depth / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * pixelSizeInBytes );
+ int outIndex = 0;
+
+ assert( (width == 1 || height == 1) && depth >= 2 );
+
+ if( width == height ) {
+ assert( width == 1 && height == 1 );
+ assert( depth >= 2 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ float totals[] = new float[4];
+ float extractTotals[][] = new float[BOX2][4];
+ int cc;
+
+ dataIn.position( src );
+ extract.extract( isSwap, dataIn, extractTotals[0] );
+ dataIn.position( src + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[1] );
+
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+
+ // average only 2 pixels since a column
+ totals[cc]= 0.0f;
+ for( kk = 0; kk < BOX2; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= BOX2;
+ } // for cc
+
+ extract.shove( totals, outIndex, dataOut );
+ outIndex++;
+ // skip over to next group of 2
+ src += imageSizeInBytes + imageSizeInBytes;
+ } // for ii
+ } else if( height == 1 ) {
+ assert( width != 1 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float totals[] = new float[4];
+ float extractTotals[][] = new float[BOX4][4];
+ int cc;
+
+ dataIn.position( src );
+ extract.extract( isSwap, dataIn, extractTotals[0] );
+ dataIn.position( src + pixelSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[1] );
+ dataIn.position( src + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[2] );
+ dataIn.position( src + pixelSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[3] );
+
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc]+= extractTotals[kk][cc];
+ }
+ totals[cc]/= (float)BOX4;
+ }
+ extract.shove( totals, outIndex, dataOut );
+ outIndex++;
+ // skip over to next horizontal square of 4
+ src += imageSizeInBytes + imageSizeInBytes;
+ }
+ }
+ } else if( width == 1 ) {
+ assert( height != 1 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float totals[] = new float[4];
+ float extractTotals[][] = new float[BOX4][4];
+ int cc;
+
+ dataIn.position( src );
+ extract.extract( isSwap, dataIn, extractTotals[0] );
+ dataIn.position( src + rowSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[1] );
+ dataIn.position( src + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[2] );
+ dataIn.position( src + rowSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[3] );
+
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc]+= extractTotals[kk][cc];
+ }
+ totals[cc]/= (float)BOX4;
+ }
+ extract.shove( totals, outIndex, dataOut );
+ outIndex++;
+ // skip over to next horizontal square of 4
+ src += imageSizeInBytes + imageSizeInBytes;
+ }
+ }
+ }
+ }
+
+ public static void halveImageSlice( int components, ExtractPrimitive extract, int width,
+ int height, int depth, ByteBuffer dataIn, ByteBuffer dataOut,
+ int elementSizeInBytes, int groupSizeInBytes, int rowSizeInBytes,
+ int imageSizeInBytes, boolean isSwap ) {
+ int ii, jj;
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int halfDepth = depth / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * groupSizeInBytes );
+ int outIndex = 0;
+
+ assert( (width == 1 || height == 1) && depth >= 2 );
+
+ if( width == height ) {
+ assert( width == 1 && height == 1 );
+ assert( depth >= 2 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ int cc;
+ for( cc = 0; cc < components; cc++ ) {
+ double[] totals = new double[4];
+ double[][] extractTotals = new double[BOX2][4];
+ int kk;
+
+ dataIn.position( src );
+ extractTotals[0][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes );
+ extractTotals[1][cc] = extract.extract( isSwap, dataIn );
+
+ // average 2 pixels since only a column
+ totals[cc] = 0.0f;
+ // totals[red] = extractTotals[0][red] + extractTotals[1][red];
+ // totals[red] = red / 2;
+ for( kk = 0; kk < BOX2; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (double)BOX2;
+
+ extract.shove( totals[cc], outIndex, dataOut );
+ outIndex++;
+ src += elementSizeInBytes;
+ } // for cc
+ // skip over next group of 2
+ src += rowSizeInBytes;
+ } // for ii
+
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfDepth * components );
+ } else if( height == 1 ) {
+ assert( width != 1 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int cc;
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+ double totals[] = new double[4];
+ double extractTotals[][] = new double[BOX4][4];
+
+ dataIn.position( src );
+ extractTotals[0][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + groupSizeInBytes );
+ extractTotals[1][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes );
+ extractTotals[2][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes + groupSizeInBytes );
+ extractTotals[3][cc] = extract.extract( isSwap, dataIn );
+
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ // totals[red] = extractTotals[0][red] + extractTotals[1][red] +
+ // extractTotals[2][red] + extractTotals[3][red];
+ // totals[red] /= (double)BOX4;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (double)BOX4;
+
+ extract.shove( totals[cc], outIndex, dataOut );
+ outIndex++;
+ src += elementSizeInBytes;
+ } // for cc
+ // skip over to next horizontal square of 4
+ src += elementSizeInBytes;
+ } // for jj
+ src += padBytes;
+ src += rowSizeInBytes;
+ } // for ii
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfWidth * halfDepth * components );
+ } else if( width == 1 ) {
+ assert( height != 1 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int cc;
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+ double totals[] = new double[4];
+ double extractTotals[][] = new double[BOX4][4];
+
+ dataIn.position( src );
+ extractTotals[0][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes );
+ extractTotals[1][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes );
+ extractTotals[2][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes + groupSizeInBytes );
+ extractTotals[3][cc] = extract.extract( isSwap, dataIn );
+
+
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ // totals[red] = extractTotals[0][red] + extractTotals[1][red] +
+ // extractTotals[2][red] + extractTotals[3][red];
+ // totals[red] /= (double)BOX4;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (double)BOX4;
+
+ extract.shove( totals[cc], outIndex, dataOut );
+ outIndex++;
+ src += elementSizeInBytes;
+ } // for cc
+ // skip over to next horizontal square of 4
+ src += padBytes;
+ src += rowSizeInBytes;
+ } // for jj
+ src += imageSizeInBytes;
+ } // for ii
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfWidth * halfDepth * components );
+ }
+ }
+
+ public static void halveImage3D( int components, ExtractPrimitive extract,
+ int width, int height, int depth, ByteBuffer dataIn, ByteBuffer dataOut,
+ int elementSizeInBytes, int groupSizeInBytes, int rowSizeInBytes,
+ int imageSizeInBytes, boolean isSwap ) {
+ assert( depth > 1 );
+
+ // horizontal/vertical/onecolumn slice viewed from top
+ if( width == 1 || height == 1 ) {
+ assert( 1 <= depth );
+
+ halveImageSlice( components, extract, width, height, depth, dataIn, dataOut,
+ elementSizeInBytes, groupSizeInBytes, rowSizeInBytes, imageSizeInBytes,
+ isSwap );
+ return;
+ }
+
+ int ii, jj, dd;
+
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int halfDepth = depth / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * groupSizeInBytes );
+ int outIndex = 0;
+
+ for( dd = 0; dd < halfDepth; dd++ ) {
+ for( ii = 0; ii < halfHeight; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int cc;
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+ double totals[] = new double[4];
+ double extractTotals[][] = new double[BOX8][4];
+
+ dataIn.position( src );
+ extractTotals[0][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + groupSizeInBytes );
+ extractTotals[1][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes );
+ extractTotals[2][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes + groupSizeInBytes );
+ extractTotals[3][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes );
+ extractTotals[4][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + groupSizeInBytes + imageSizeInBytes );
+ extractTotals[5][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes + imageSizeInBytes );
+ extractTotals[6][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes + imageSizeInBytes + groupSizeInBytes );
+ extractTotals[7][cc] = extract.extract( isSwap, dataIn );
+
+ totals[cc] = 0.0f;
+
+ for( kk = 0; kk < BOX8; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (double)BOX8;
+
+ extract.shove( totals[cc], outIndex, dataOut );
+ outIndex++;
+
+ src += elementSizeInBytes;
+ } // for cc
+ // skip over to next square of 4
+ src += groupSizeInBytes;
+ } // for jj
+ // skip past pad bytes, if any, to get to next row
+ src += padBytes;
+ src += rowSizeInBytes;
+ } // for ii
+ src += imageSizeInBytes;
+ } // for dd
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfWidth * halfHeight * halfDepth * components );
+ }
+
+ public static void halveImagePackedPixel3D( int components, Extract extract,
+ int width, int height, int depth, ByteBuffer dataIn,
+ ByteBuffer dataOut, int pixelSizeInBytes, int rowSizeInBytes,
+ int imageSizeInBytes, boolean isSwap ) {
+ if( depth == 1 ) {
+ assert( 1 <= width && 1 <= height );
+
+ halveImagePackedPixel( components, extract, width, height, dataIn, dataOut,
+ pixelSizeInBytes, rowSizeInBytes, isSwap );
+ return;
+ } else if( width == 1 || height == 1 ) { // a horizontal or vertical slice viewed from top
+ assert( 1 <= depth );
+
+ halveImagePackedPixelSlice( components, extract, width, height, depth, dataIn,
+ dataOut, pixelSizeInBytes, rowSizeInBytes, imageSizeInBytes, isSwap );
+ return;
+ }
+ int ii, jj, dd;
+
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int halfDepth = depth / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * pixelSizeInBytes );
+ int outIndex = 0;
+
+ for( dd = 0; dd < halfDepth; dd++ ) {
+ for( ii = 0; ii < halfHeight; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float totals[] = new float[4]; // 4 is max components
+ float extractTotals[][] = new float[BOX8][4];
+ int cc;
+
+ dataIn.position( src );
+ extract.extract( isSwap, dataIn, extractTotals[0] );
+ dataIn.position( src + pixelSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[1] );
+ dataIn.position( src + rowSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[2] );
+ dataIn.position( src + rowSizeInBytes + pixelSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[3] );
+ dataIn.position( src + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[4] );
+ dataIn.position( src + pixelSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[5] );
+ dataIn.position( src + rowSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[6] );
+ dataIn.position( src + rowSizeInBytes + pixelSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[7] );
+
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+ // grab 8 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX8; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (float)BOX8;
+ }
+ extract.shove( totals, outIndex, dataOut );
+ outIndex++;
+ // skip over to next square of 4
+ src += pixelSizeInBytes + pixelSizeInBytes;
+ }
+ // skip past pad bytes, if any, to get to next row
+ src += padBytes;
+ src += rowSizeInBytes;
+ }
+ src += imageSizeInBytes;
+ }
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfWidth * halfHeight * halfDepth );
+ }
+}