/* EncodeRGB16.java --
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.javax.imageio.bmp;

import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.io.IOException;

import javax.imageio.IIOImage;
import javax.imageio.ImageWriteParam;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageOutputStream;

public class EncodeRGB16
    extends BMPEncoder
{
  protected BMPInfoHeader infoHeader;
  protected BMPFileHeader fileHeader;
  protected long offset;

  /**
   * Constructs an instance of this class.
   *
   * @param fh - the file header to use.
   * @param ih - the info header to use.
   */
  public EncodeRGB16(BMPFileHeader fh, BMPInfoHeader ih)
  {
    super();
    fileHeader = fh;
    infoHeader = ih;
    offset = BMPFileHeader.SIZE + BMPInfoHeader.SIZE;
  }

  /**
   * The image encoder.
   *
   * @param o - the image output stream
   * @param streamMetadata - metadata associated with this stream, or
   * null
   * @param image - an IIOImage containing image data.
   * @param param - image writing parameters, or null
   * @exception IOException if a write error occurs
   */
  public void encode(ImageOutputStream o, IIOMetadata streamMetadata,
                     IIOImage image, ImageWriteParam param) throws IOException
  {
    int size;
    int value;
    int j;
    int rowCount;
    int rowIndex;
    int lastRowIndex;
    int[] bitmap;
    byte rgb[] = new byte[2];
    size = (infoHeader.biWidth * infoHeader.biHeight) - 1;
    rowCount = 1;
    rowIndex = size - infoHeader.biWidth;
    lastRowIndex = rowIndex;
    try
      {
        bitmap = new int[infoHeader.biWidth * infoHeader.biHeight];
        PixelGrabber pg = new PixelGrabber((BufferedImage) image.getRenderedImage(),
                                           0, 0, infoHeader.biWidth,
                                           infoHeader.biHeight, bitmap, 0,
                                           infoHeader.biWidth);
        pg.grabPixels();

        for (j = 0; j < size; j++)
          {
            value = bitmap[rowIndex];

            rgb[0] = (byte) (value & 0xFF);
            rgb[1] = (byte) (value >> 8 & 0xFF);

            o.write(rgb);
            if (rowCount == infoHeader.biWidth)
              {
                rowCount = 1;
                rowIndex = lastRowIndex - infoHeader.biWidth;
                lastRowIndex = rowIndex;
              }
            else
              rowCount++;
            rowIndex++;
          }
      }
    catch (Exception wb)
      {
        wb.printStackTrace();
      }
  }
}
