public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
   int type = getTransferType();
   Object ret = null;
   switch (type) {
     case DataBuffer.TYPE_BYTE:
       {
         byte[] in = (byte[]) obj;
         if (in == null) in = new byte[1];
         in[0] = (byte) data.getElem(x + y * scanlineStride);
         ret = in;
       }
       break;
     case DataBuffer.TYPE_USHORT:
       {
         short[] in = (short[]) obj;
         if (in == null) in = new short[1];
         in[0] = (short) data.getElem(x + y * scanlineStride);
         ret = in;
       }
       break;
     case DataBuffer.TYPE_INT:
       {
         int[] in = (int[]) obj;
         if (in == null) in = new int[1];
         in[0] = data.getElem(x + y * scanlineStride);
         ret = in;
       }
       break;
   }
   return ret;
 }
 @Override
 public void renderPadPixel(
     final ImageMask imageMask, final DataBuffer data, final int pixelIndex) {
   if (imageMask.isPadPixel(data.getElem(pixelIndex))) {
     data.setElem(pixelIndex, 0x00000000);
   }
 }
  /**
   * Sets all samples for a rectangle of pixels from an int array containing one sample per array
   * element. ArrayIndexOutOfBoundsException may be thrown if the coordinates are not in bounds.
   *
   * @param x The X coordinate of the upper left pixel location.
   * @param y The Y coordinate of the upper left pixel location.
   * @param w The width of the pixel rectangle.
   * @param h The height of the pixel rectangle.
   * @param iArray The input samples in an int array.
   * @param data The DataBuffer containing the image data.
   * @see #getPixels(int, int, int, int, int[], DataBuffer)
   */
  public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
    int x1 = x + w;
    int y1 = y + h;

    if (x < 0
        || x >= width
        || w > width
        || x1 < 0
        || x1 > width
        || y < 0
        || y >= height
        || h > height
        || y1 < 0
        || y1 > height) {
      throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
    }

    int lineOffset = y * scanlineStride + x;
    int srcOffset = 0;

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        int value = data.getElem(lineOffset + j);
        for (int k = 0; k < numBands; k++) {
          value &= ~bitMasks[k];
          int srcValue = iArray[srcOffset++];
          value |= ((srcValue << bitOffsets[k]) & bitMasks[k]);
        }
        data.setElem(lineOffset + j, value);
      }
      lineOffset += scanlineStride;
    }
  }
 public int getAlpha(Object inData) {
   DataBuffer buffer = Buffers.createBufferFromData(transferType, inData, getNumComponents());
   int shift = 8 - getComponentSize(getNumColorComponents());
   int alpha = buffer.getElem(getNumColorComponents());
   if (shift >= 0) return alpha << shift;
   return alpha >> (-shift);
 }
 /**
  * Returns as int the sample in a specified band for the pixel located at (x,y).
  * ArrayIndexOutOfBoundsException may be thrown if the coordinates are not in bounds.
  *
  * @param x The X coordinate of the pixel location.
  * @param y The Y coordinate of the pixel location.
  * @param b The band to return.
  * @param data The DataBuffer containing the image data.
  * @return the sample in a specified band for the specified pixel.
  * @see #setSample(int, int, int, int, DataBuffer)
  */
 public int getSample(int x, int y, int b, DataBuffer data) {
   // Bounds check for 'b' will be performed automatically
   if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
     throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
   }
   int sample = data.getElem(y * scanlineStride + x);
   return ((sample & bitMasks[b]) >>> bitOffsets[b]);
 }
 /**
  * Sets the sample value for a band for the pixel at (x, y) in the specified data buffer.
  *
  * @param x the x-coordinate of the pixel.
  * @param y the y-coordinate of the pixel.
  * @param b the band (in the range <code>0</code> to <code>getNumBands() - 1</code>).
  * @param s the sample value.
  * @param data the data buffer (<code>null</code> not permitted).
  * @throws NullPointerException if <code>data</code> is <code>null</code>.
  */
 public void setSample(int x, int y, int b, int s, DataBuffer data) {
   int offset = scanlineStride * y + x;
   int samples = data.getElem(offset);
   int bitMask = bitMasks[b];
   samples &= ~bitMask;
   samples |= (s << bitOffsets[b]) & bitMask;
   data.setElem(offset, samples);
 }
  /**
   * Returns data for a single pixel in a primitive array of type TransferType. For a
   * SinglePixelPackedSampleModel, the array will have one element, and the type will be the same as
   * the storage data type. Generally, obj should be passed in as null, so that the Object will be
   * created automatically and will be of the right primitive data type.
   *
   * <p>The following code illustrates transferring data for one pixel from DataBuffer <code>db1
   * </code>, whose storage layout is described by SinglePixelPackedSampleModel <code>sppsm1</code>,
   * to DataBuffer <code>db2</code>, whose storage layout is described by
   * SinglePixelPackedSampleModel <code>sppsm2</code>. The transfer will generally be more efficient
   * than using getPixel/setPixel.
   *
   * <pre>
   *       SinglePixelPackedSampleModel sppsm1, sppsm2;
   *       DataBufferInt db1, db2;
   *       sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
   *                              db1), db2);
   * </pre>
   *
   * Using getDataElements/setDataElements to transfer between two DataBuffer/SampleModel pairs is
   * legitimate if the SampleModels have the same number of bands, corresponding bands have the same
   * number of bits per sample, and the TransferTypes are the same.
   *
   * <p>If obj is non-null, it should be a primitive array of type TransferType. Otherwise, a
   * ClassCastException is thrown. An ArrayIndexOutOfBoundsException may be thrown if the
   * coordinates are not in bounds, or if obj is non-null and is not large enough to hold the pixel
   * data.
   *
   * @param x The X coordinate of the pixel location.
   * @param y The Y coordinate of the pixel location.
   * @param obj If non-null, a primitive array in which to return the pixel data.
   * @param data The DataBuffer containing the image data.
   * @return the data for the specified pixel.
   * @see #setDataElements(int, int, Object, DataBuffer)
   */
  public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
    // Bounds check for 'b' will be performed automatically
    if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
      throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
    }

    int type = getTransferType();

    switch (type) {
      case DataBuffer.TYPE_BYTE:
        byte[] bdata;

        if (obj == null) bdata = new byte[1];
        else bdata = (byte[]) obj;

        bdata[0] = (byte) data.getElem(y * scanlineStride + x);

        obj = (Object) bdata;
        break;

      case DataBuffer.TYPE_USHORT:
        short[] sdata;

        if (obj == null) sdata = new short[1];
        else sdata = (short[]) obj;

        sdata[0] = (short) data.getElem(y * scanlineStride + x);

        obj = (Object) sdata;
        break;

      case DataBuffer.TYPE_INT:
        int[] idata;

        if (obj == null) idata = new int[1];
        else idata = (int[]) obj;

        idata[0] = data.getElem(y * scanlineStride + x);

        obj = (Object) idata;
        break;
    }

    return obj;
  }
  /**
   * Returns an array containing the samples for the pixel at (x, y) in the specified data buffer.
   * If <code>iArray</code> is not <code>null</code>, it will be populated with the sample values
   * and returned as the result of this function (this avoids allocating a new array instance).
   *
   * @param x the x-coordinate of the pixel.
   * @param y the y-coordinate of the pixel.
   * @param iArray an array to populate with the sample values and return as the result (if <code>
   *     null</code>, a new array will be allocated).
   * @param data the data buffer (<code>null</code> not permitted).
   * @return The pixel sample values.
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
   */
  public int[] getPixel(int x, int y, int[] iArray, DataBuffer data) {
    int offset = scanlineStride * y + x;
    if (iArray == null) iArray = new int[numBands];
    int samples = data.getElem(offset);

    for (int b = 0; b < numBands; b++) iArray[b] = (samples & bitMasks[b]) >>> bitOffsets[b];

    return iArray;
  }
 /**
  * Sets a sample in the specified band for the pixel located at (x,y) in the DataBuffer using an
  * int for input. ArrayIndexOutOfBoundsException may be thrown if the coordinates are not in
  * bounds.
  *
  * @param x The X coordinate of the pixel location.
  * @param y The Y coordinate of the pixel location.
  * @param b The band to set.
  * @param s The input sample as an int.
  * @param data The DataBuffer containing the image data.
  * @see #getSample(int, int, int, DataBuffer)
  */
 public void setSample(int x, int y, int b, int s, DataBuffer data) {
   // Bounds check for 'b' will be performed automatically
   if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
     throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
   }
   int value = data.getElem(y * scanlineStride + x);
   value &= ~bitMasks[b];
   value |= (s << bitOffsets[b]) & bitMasks[b];
   data.setElem(y * scanlineStride + x, value);
 }
  public int[] getComponents(Object pixel, int[] components, int offset) {
    DataBuffer buffer = Buffers.createBuffer(transferType, pixel, getNumComponents());
    int numComponents = getNumComponents();

    if (components == null) components = new int[numComponents + offset];

    for (int i = 0; i < numComponents; i++) components[offset++] = buffer.getElem(i);

    return components;
  }
 /**
  * Sets a pixel in the DataBuffer using an int array of samples for input.
  * ArrayIndexOutOfBoundsException may be thrown if the coordinates are not in bounds.
  *
  * @param x The X coordinate of the pixel location.
  * @param y The Y coordinate of the pixel location.
  * @param iArray The input samples in an int array.
  * @param data The DataBuffer containing the image data.
  * @see #getPixel(int, int, int[], DataBuffer)
  */
 public void setPixel(int x, int y, int iArray[], DataBuffer data) {
   if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
     throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
   }
   int lineOffset = y * scanlineStride + x;
   int value = data.getElem(lineOffset);
   for (int i = 0; i < numBands; i++) {
     value &= ~bitMasks[i];
     value |= ((iArray[i] << bitOffsets[i]) & bitMasks[i]);
   }
   data.setElem(lineOffset, value);
 }
 @Override
 public void renderPixelBand(
     final DataBuffer data,
     final int pixelIndex,
     final ImageInputStream imageInputStream,
     final int bandIndex)
     throws IOException {
   data.setElem(
       pixelIndex,
       ALPHA_MASK
           | data.getElem(pixelIndex)
           | (imageInputStream.read() << bandMapping.get(bandIndex)));
 }
Пример #13
0
  private void readImage(String file) {
    Util.c_log("reading " + file);

    BufferedImage img = null;
    try {
      img = ImageIO.read(new File(file));
    } catch (IOException e) {
      Util.c_log("ERROR: " + e.toString());
    }

    height = img.getHeight();
    width = img.getWidth();

    pixelShould = new byte[height][width][3];
    int[] result = new int[height * width * 3 + 1];

    // img.getData().getPixels(0, 0, height, width, result);
    DataBuffer buffer = img.getData().getDataBuffer();
    short k = 0;

    for (int i = 0; i < height * width; i++) {
      pixelShould[i % height][(int) ((float) i / (float) height)][R] =
          (byte) buffer.getElem(3 * i + R);
      pixelShould[i % height][(int) ((float) i / (float) height)][G] =
          (byte) buffer.getElem(3 * i + G);
      pixelShould[i % height][(int) ((float) i / (float) height)][B] =
          (byte) buffer.getElem(3 * i + B);
      // Log.debug("reading pixel: (" + i % height + "|" + (int) ((float) i / (float) height) + "):
      // [" + buffer.getElem(3 * i + R) + "|" + buffer.getElem(3 * i + G) + "|" + buffer.getElem(3 *
      // i + B) + "]");

      if ((float) i / (float) (height * width) * 100 > k + 10) {
        k += 10;
        Util.c_log(k + "%");
      }
    }
    img = null;
    Util.c_log("finished.");
  }
 /**
  * Returns an array containing the samples for the pixels in the region specified by (x, y, w, h)
  * in the specified data buffer. The array is ordered by pixels (that is, all the samples for the
  * first pixel are grouped together, followed by all the samples for the second pixel, and so on).
  * If <code>iArray</code> is not <code>null</code>, it will be populated with the sample values
  * and returned as the result of this function (this avoids allocating a new array instance).
  *
  * @param x the x-coordinate of the top-left pixel.
  * @param y the y-coordinate of the top-left pixel.
  * @param w the width of the region of pixels.
  * @param h the height of the region of pixels.
  * @param iArray an array to populate with the sample values and return as the result (if <code>
  *     null</code>, a new array will be allocated).
  * @param data the data buffer (<code>null</code> not permitted).
  * @return The pixel sample values.
  * @throws NullPointerException if <code>data</code> is <code>null</code>.
  */
 public int[] getPixels(int x, int y, int w, int h, int[] iArray, DataBuffer data) {
   int offset = scanlineStride * y + x;
   if (iArray == null) iArray = new int[numBands * w * h];
   int outOffset = 0;
   for (y = 0; y < h; y++) {
     int lineOffset = offset;
     for (x = 0; x < w; x++) {
       int samples = data.getElem(lineOffset++);
       for (int b = 0; b < numBands; b++)
         iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
     }
     offset += scanlineStride;
   }
   return iArray;
 }
  /**
   * Returns all samples in for the specified pixel in an int array. ArrayIndexOutOfBoundsException
   * may be thrown if the coordinates are not in bounds.
   *
   * @param x The X coordinate of the pixel location.
   * @param y The Y coordinate of the pixel location.
   * @param iArray If non-null, returns the samples in this array
   * @param data The DataBuffer containing the image data.
   * @return all samples for the specified pixel.
   * @see #setPixel(int, int, int[], DataBuffer)
   */
  public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
    if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
      throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
    }
    int pixels[];
    if (iArray == null) {
      pixels = new int[numBands];
    } else {
      pixels = iArray;
    }

    int value = data.getElem(y * scanlineStride + x);
    for (int i = 0; i < numBands; i++) {
      pixels[i] = (value & bitMasks[i]) >>> bitOffsets[i];
    }
    return pixels;
  }
  /**
   * Sets the samples in the specified band for the specified rectangle of pixels from an int array
   * containing one sample per array element. ArrayIndexOutOfBoundsException may be thrown if the
   * coordinates are not in bounds.
   *
   * @param x The X coordinate of the upper left pixel location.
   * @param y The Y coordinate of the upper left pixel location.
   * @param w The width of the pixel rectangle.
   * @param h The height of the pixel rectangle.
   * @param b The band to set.
   * @param iArray The input samples in an int array.
   * @param data The DataBuffer containing the image data.
   * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
   */
  public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
    // Bounds check for 'b' will be performed automatically
    if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
      throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
    }
    int lineOffset = y * scanlineStride + x;
    int srcOffset = 0;

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        int value = data.getElem(lineOffset + j);
        value &= ~bitMasks[b];
        int sample = iArray[srcOffset++];
        value |= ((int) sample << bitOffsets[b]) & bitMasks[b];
        data.setElem(lineOffset + j, value);
      }
      lineOffset += scanlineStride;
    }
  }
Пример #17
0
  public void encodeWBMP(RenderedImage renderedImage, OutputStream os) throws IOException {

    BufferedImage bufferedImage = getBufferedImage(renderedImage);

    SampleModel sampleModel = bufferedImage.getSampleModel();

    int type = sampleModel.getDataType();

    if ((bufferedImage.getType() != BufferedImage.TYPE_BYTE_BINARY)
        || (type < DataBuffer.TYPE_BYTE)
        || (type > DataBuffer.TYPE_INT)
        || (sampleModel.getNumBands() != 1)
        || (sampleModel.getSampleSize(0) != 1)) {

      BufferedImage binaryImage =
          new BufferedImage(
              bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_BYTE_BINARY);

      Graphics graphics = binaryImage.getGraphics();

      graphics.drawImage(bufferedImage, 0, 0, null);

      renderedImage = binaryImage;
    }

    if (!ImageIO.write(renderedImage, "wbmp", os)) {

      // See http://www.jguru.com/faq/view.jsp?EID=127723

      os.write(0);
      os.write(0);
      os.write(toMultiByte(bufferedImage.getWidth()));
      os.write(toMultiByte(bufferedImage.getHeight()));

      DataBuffer dataBuffer = bufferedImage.getData().getDataBuffer();

      int size = dataBuffer.getSize();

      for (int i = 0; i < size; i++) {
        os.write((byte) dataBuffer.getElem(i));
      }
    }
  }
  /**
   * Returns the samples for a specified band for the specified rectangle of pixels in an int array,
   * one sample per array element. ArrayIndexOutOfBoundsException may be thrown if the coordinates
   * are not in bounds.
   *
   * @param x The X coordinate of the upper left pixel location.
   * @param y The Y coordinate of the upper left pixel location.
   * @param w The width of the pixel rectangle.
   * @param h The height of the pixel rectangle.
   * @param b The band to return.
   * @param iArray If non-null, returns the samples in this array.
   * @param data The DataBuffer containing the image data.
   * @return the samples for the specified band for the specified region of pixels.
   * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
   */
  public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
    // Bounds check for 'b' will be performed automatically
    if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
      throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
    }
    int samples[];
    if (iArray != null) {
      samples = iArray;
    } else {
      samples = new int[w * h];
    }
    int lineOffset = y * scanlineStride + x;
    int dstOffset = 0;

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        int value = data.getElem(lineOffset + j);
        samples[dstOffset++] = ((value & bitMasks[b]) >>> bitOffsets[b]);
      }
      lineOffset += scanlineStride;
    }
    return samples;
  }
  /**
   * Returns all samples for the specified rectangle of pixels in an int array, one sample per array
   * element. ArrayIndexOutOfBoundsException may be thrown if the coordinates are not in bounds.
   *
   * @param x The X coordinate of the upper left pixel location.
   * @param y The Y coordinate of the upper left pixel location.
   * @param w The width of the pixel rectangle.
   * @param h The height of the pixel rectangle.
   * @param iArray If non-null, returns the samples in this array.
   * @param data The DataBuffer containing the image data.
   * @return all samples for the specified region of pixels.
   * @see #setPixels(int, int, int, int, int[], DataBuffer)
   */
  public int[] getPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
    int x1 = x + w;
    int y1 = y + h;

    if (x < 0
        || x >= width
        || w > width
        || x1 < 0
        || x1 > width
        || y < 0
        || y >= height
        || h > height
        || y1 < 0
        || y1 > height) {
      throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
    }
    int pixels[];
    if (iArray != null) {
      pixels = iArray;
    } else {
      pixels = new int[w * h * numBands];
    }
    int lineOffset = y * scanlineStride + x;
    int dstOffset = 0;

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        int value = data.getElem(lineOffset + j);
        for (int k = 0; k < numBands; k++) {
          pixels[dstOffset++] = ((value & bitMasks[k]) >>> bitOffsets[k]);
        }
      }
      lineOffset += scanlineStride;
    }
    return pixels;
  }
 /**
  * Returns the sample value for the pixel at (x, y) in the specified data buffer.
  *
  * @param x the x-coordinate of the pixel.
  * @param y the y-coordinate of the pixel.
  * @param b the band (in the range <code>0</code> to <code>getNumBands() - 1</code>).
  * @param data the data buffer (<code>null</code> not permitted).
  * @return The sample value.
  * @throws NullPointerException if <code>data</code> is <code>null</code>.
  */
 public int getSample(int x, int y, int b, DataBuffer data) {
   int offset = scanlineStride * y + x;
   int samples = data.getElem(offset);
   return (samples & bitMasks[b]) >>> bitOffsets[b];
 }
Пример #21
0
 public void runTest(Object context, int numReps) {
   DataBuffer db = ((Context) context).db;
   do {
     db.getElem(numReps & 7);
   } while (--numReps > 0);
 }
  protected RenderedImage convert(RenderedImage renderedImage) throws Exception {

    int height = renderedImage.getHeight();
    int width = renderedImage.getWidth();

    SampleModel sampleModel = renderedImage.getSampleModel();
    ColorModel colorModel = renderedImage.getColorModel();

    Raster raster = renderedImage.getData();

    DataBuffer dataBuffer = raster.getDataBuffer();

    if (colorModel instanceof IndexColorModel) {
      IndexColorModel indexColorModel = (IndexColorModel) colorModel;

      int mapSize = indexColorModel.getMapSize();

      byte[][] data = new byte[4][mapSize];

      indexColorModel.getReds(data[0]);
      indexColorModel.getGreens(data[1]);
      indexColorModel.getBlues(data[2]);
      indexColorModel.getAlphas(data[3]);

      LookupTableJAI lookupTableJAI = new LookupTableJAI(data);

      renderedImage = LookupDescriptor.create(renderedImage, lookupTableJAI, null);
    } else if (sampleModel.getNumBands() == 2) {
      List<Byte> bytesList = new ArrayList<Byte>(height * width * _NUM_OF_BANDS);

      List<Byte> tempBytesList = new ArrayList<Byte>(_NUM_OF_BANDS);

      for (int i = 0; i < dataBuffer.getSize(); i++) {
        int mod = (i + 1) % 2;

        int elemPos = i;

        if (mod == 0) {
          tempBytesList.add((byte) dataBuffer.getElem(elemPos - 1));
          tempBytesList.add((byte) dataBuffer.getElem(elemPos - 1));
        }

        tempBytesList.add((byte) dataBuffer.getElem(elemPos));

        if (mod == 0) {
          Collections.reverse(tempBytesList);

          bytesList.addAll(tempBytesList);

          tempBytesList.clear();
        }
      }

      byte[] data = ArrayUtil.toArray(bytesList.toArray(new Byte[bytesList.size()]));

      DataBuffer newDataBuffer = new DataBufferByte(data, data.length);

      renderedImage = createRenderedImage(renderedImage, height, width, newDataBuffer);
    } else if (colorModel.getTransparency() != Transparency.TRANSLUCENT) {
      List<Byte> bytesList = new ArrayList<Byte>(height * width * _NUM_OF_BANDS);

      List<Byte> tempBytesList = new ArrayList<Byte>(_NUM_OF_BANDS);

      for (int i = 0; i < dataBuffer.getSize(); i++) {
        int mod = (i + 1) % 3;

        int elemPos = i;

        tempBytesList.add((byte) dataBuffer.getElem(elemPos));

        if (mod == 0) {
          tempBytesList.add((byte) 255);

          Collections.reverse(tempBytesList);

          bytesList.addAll(tempBytesList);

          tempBytesList.clear();
        }
      }

      byte[] data = ArrayUtil.toArray(bytesList.toArray(new Byte[bytesList.size()]));

      DataBuffer newDataBuffer = new DataBufferByte(data, data.length);

      renderedImage = createRenderedImage(renderedImage, height, width, newDataBuffer);
    }

    return renderedImage;
  }
Пример #23
0
  public void compressImage(
      java.awt.image.BufferedImage image,
      DXTCompressionAttributes attributes,
      java.nio.ByteBuffer buffer) {
    if (image == null) {
      String message = Logging.getMessage("nullValue.ImageIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (attributes == null) {
      String message = Logging.getMessage("nullValue.AttributesIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (buffer == null) {
      String message = Logging.getMessage("nullValue.BufferNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    int[] band = {0, 1, 2};
    Raster child =
        image.getData().createChild(0, 0, image.getWidth(), image.getHeight(), 0, 0, band);

    // If it is determined that the image and block have no alpha component, then we compress with
    // DXT1 using a
    // four color palette. Otherwise, we use the three color palette (with the fourth color as
    // transparent black).
    final int kYMask[] = {0x0, 0xf, 0xff, 0xfff, 0xffff};
    final int kXMask[] = {0x0, 0x1111, 0x3333, 0x7777, 0xffff};
    byte[] block = new byte[ETCConstants.DECODED_BLOCK_SIZE];
    byte[] encoded = new byte[ETCConstants.ENCODED_BLOCK_SIZE];

    int width = child.getWidth();
    int height = child.getHeight();

    int encodedWidth = (width + 3) & ~3;
    int encodedHeight = (height + 3) & ~3;

    int pixelSize = 1;

    int stride = pixelSize * width;

    DataBuffer pIn = child.getDataBuffer();

    for (int y = 0; y < encodedHeight; y += 4) {
      int yEnd = height - y;
      if (yEnd > 4) {
        yEnd = 4;
      }
      int ymask = kYMask[yEnd];
      for (int x = 0; x < encodedWidth; x += 4) {
        int xEnd = width - x;
        if (xEnd > 4) {
          xEnd = 4;
        }
        int mask = ymask & kXMask[xEnd];
        for (int cy = 0; cy < yEnd; cy++) {
          int q = (cy * 4) * 3;
          int p = pixelSize * x + stride * (y + cy);
          // (pixelSize == 1 * 32 bit) {
          for (int cx = 0; cx < xEnd; cx++) {
            int pixel = pIn.getElem(p);
            block[q++] = (byte) ((pixel >> 16) & 0xFF);
            block[q++] = (byte) ((pixel >> 8) & 0xFF);
            block[q++] = (byte) (pixel & 0xFF);
            p += pixelSize;
          }
        }
        BlockETC1Compressor.encodeBlock(block, mask, encoded);
        buffer.put(encoded);
      }
    }
  }