/* JPEGDecoder.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.jpeg;

import java.io.IOException;
import java.nio.ByteOrder;

import javax.imageio.*;
import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
import javax.imageio.plugins.jpeg.JPEGQTable;
import javax.imageio.spi.*;
import javax.imageio.metadata.*;
import javax.imageio.stream.ImageInputStream;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;

public class JPEGDecoder
{
  byte majorVersion;
  byte minorVersion;
  byte units;
  short Xdensity;
  short Ydensity;
  byte Xthumbnail;
  byte Ythumbnail;
  byte[] thumbnail;
  BufferedImage image;
  int width;
  int height;
  
  byte marker;

  /**
   * This decoder expects JFIF 1.02 encoding.
   */
  public static final byte MAJOR_VERSION = (byte) 1;
  public static final byte MINOR_VERSION = (byte) 2;

  /**
   * The length of the JFIF field not including thumbnail data.
   */
  public static final short JFIF_FIXED_LENGTH = 16;

  /**
   * The length of the JFIF extension field not including extension
   * data.
   */
  public static final short JFXX_FIXED_LENGTH = 8;

  private JPEGImageInputStream jpegStream;

  ArrayList jpegFrames = new ArrayList();

  JPEGHuffmanTable[] dcTables = new JPEGHuffmanTable[4];
  JPEGHuffmanTable[] acTables = new JPEGHuffmanTable[4];
  JPEGQTable[] qTables = new JPEGQTable[4];

    public int getHeight()
    {
      return height;
    }
    
    public int getWidth()
    {
        return width;
    }
  public JPEGDecoder(ImageInputStream in)
    throws IOException, JPEGException
  {
    jpegStream = new JPEGImageInputStream(in);
    jpegStream.setByteOrder(ByteOrder.LITTLE_ENDIAN);

    if (jpegStream.findNextMarker() != JPEGMarker.SOI)
      throw new JPEGException("Failed to find SOI marker.");

    if (jpegStream.findNextMarker() != JPEGMarker.APP0)
      throw new JPEGException("Failed to find APP0 marker.");

    int length = jpegStream.readShort();
    if (!(length >= JFIF_FIXED_LENGTH))
      throw new JPEGException("Failed to find JFIF field.");

    byte[] identifier = new byte[5];
    jpegStream.read(identifier);
    if (identifier[0] != JPEGMarker.JFIF_J
        || identifier[1] != JPEGMarker.JFIF_F
        || identifier[2] != JPEGMarker.JFIF_I
        || identifier[3] != JPEGMarker.JFIF_F
        || identifier[4] != JPEGMarker.X00)
      throw new JPEGException("Failed to read JFIF identifier.");

    majorVersion = jpegStream.readByte();
    minorVersion = jpegStream.readByte();
    if (majorVersion != MAJOR_VERSION
        || (majorVersion == MAJOR_VERSION
            && minorVersion < MINOR_VERSION))
      throw new JPEGException("Unsupported JFIF version.");

    units = jpegStream.readByte();
    if (units > (byte) 2)
      throw new JPEGException("Units field is out of range.");

    Xdensity = jpegStream.readShort();
    Ydensity = jpegStream.readShort();
    Xthumbnail = jpegStream.readByte();
    Ythumbnail = jpegStream.readByte();

    // 3 * for RGB data
    int thumbnailLength = 3 * Xthumbnail * Ythumbnail;
    if (length > JFIF_FIXED_LENGTH
        && thumbnailLength != length - JFIF_FIXED_LENGTH)
      throw new JPEGException("Invalid length, Xthumbnail"
                              + " or Ythumbnail field.");

    if (thumbnailLength > 0)
      {
        thumbnail = new byte[thumbnailLength];
        if (jpegStream.read(thumbnail) != thumbnailLength)
          throw new IOException("Failed to read thumbnail.");
      }
  }

  public void decode()
    throws IOException
  {
    System.out.println ("DECODE!!!");
    // The frames in this jpeg are loaded into a list. There is
    // usually just one frame except in heirarchial progression where
    // there are multiple frames.
    JPEGFrame frame = null;

    // The restart interval defines how many MCU's we should have
    // between the 8-modulo restart marker. The restart markers allow
    // us to tell whether or not our decoding process is working
    // correctly, also if there is corruption in the image we can
    // recover with these restart intervals. (See RSTm DRI).
    int resetInterval = 0;

    // The JPEGDecoder constructor parses the JFIF field.  At this
    // point jpegStream points to the first byte after the JFIF field.

    // Find the first marker after the JFIF field.
    byte marker = jpegStream.findNextMarker();

    // Check for a JFIF extension field directly following the JFIF
    // header and advance the current marker to the next marker in the
    // stream, if necessary.
    decodeJFIFExtension();

    // Loop through until there are no more markers to read in, at
    // that point everything is loaded into the jpegFrames array and
    // can be processed.
    while (true)
      {
        switch (marker)
          {
            // APPn Application Reserved Information - Just throw this
            // information away because we wont be using it.
          case JPEGMarker.APP0:
          case JPEGMarker.APP1:
          case JPEGMarker.APP2:
          case JPEGMarker.APP3:
          case JPEGMarker.APP4:
          case JPEGMarker.APP5:
          case JPEGMarker.APP6:
          case JPEGMarker.APP7:
          case JPEGMarker.APP8:
          case JPEGMarker.APP9:
          case JPEGMarker.APP10:
          case JPEGMarker.APP11:
          case JPEGMarker.APP12:
          case JPEGMarker.APP13:
          case JPEGMarker.APP14:
          case JPEGMarker.APP15:
            jpegStream.skipBytes(jpegStream.readShort() - 2);
            break;

          case JPEGMarker.SOF0:
            // SOFn Start of Frame Marker, Baseline DCT - This is the start
            // of the frame header that defines certain variables that will
            // be carried out through the rest of the encoding. Multiple
            // frames are used in a heirarchiel system, however most JPEG's
            // only contain a single frame.
            jpegFrames.add(new JPEGFrame());
            frame = (JPEGFrame) jpegFrames.get(jpegFrames.size() - 1);
            // Skip the frame length.
            jpegStream.readShort();
            // Bits percision, either 8 or 12.
            frame.setPrecision(jpegStream.readByte());
            // Scan lines = to the height of the frame.
            frame.setScanLines(jpegStream.readShort());
            // Scan samples per line = to the width of the frame.
            frame.setSamplesPerLine(jpegStream.readShort());
            // Number of Color Components (or channels).
            frame.setComponentCount(jpegStream.readByte());

            // Set the color mode for this frame, so far only 2 color
            // modes are supported.
            if (frame.getComponentCount() == 1)
              frame.setColorMode(JPEGFrame.JPEG_COLOR_GRAY);
            else
              frame.setColorMode(JPEGFrame.JPEG_COLOR_YCbCr);
            // Add all of the necessary components to the frame.
            for (int i = 0; i < frame.getComponentCount(); i++)
              frame.addComponent(jpegStream.readByte(), jpegStream.readByte(),
                                 jpegStream.readByte());
            break;

          case JPEGMarker.SOF2:
            jpegFrames.add(new JPEGFrame());
            frame = (JPEGFrame) jpegFrames.get(jpegFrames.size() - 1);
            // Skip the frame length.
            jpegStream.readShort();
            // Bits percision, either 8 or 12.
            frame.setPrecision(jpegStream.readByte());
            // Scan lines = to the height of the frame.
            frame.setScanLines(jpegStream.readShort());
            // Scan samples per line = to the width of the frame.
            frame.setSamplesPerLine(jpegStream.readShort());
            // Number of Color Components (or channels).
            frame.setComponentCount(jpegStream.readByte());

            // Set the color mode for this frame, so far only 2 color
            // modes are supported.
            if (frame.getComponentCount() == 1)
              frame.setColorMode(JPEGFrame.JPEG_COLOR_GRAY);
            else
              frame.setColorMode(JPEGFrame.JPEG_COLOR_YCbCr);

            // Add all of the necessary components to the frame.
            for (int i = 0; i < frame.getComponentCount(); i++)
              frame.addComponent(jpegStream.readByte(), jpegStream.readByte(),
                                 jpegStream.readByte());
            break;

          case JPEGMarker.DHT:
            // DHT non-SOF Marker - Huffman Table is required for decoding
            // the JPEG stream, when we receive a marker we load in first
            // the table length (16 bits), the table class (4 bits), table
            // identifier (4 bits), then we load in 16 bytes and each byte
            // represents the count of bytes to load in for each of the 16
            // bytes. We load this into an array to use later and move on 4
            // huffman tables can only be used in an image.
            int huffmanLength = (jpegStream.readShort() - 2);

            // Keep looping until we are out of length.
            int index = huffmanLength;

            // Multiple tables may be defined within a DHT marker. This
            // will keep reading until there are no tables left, most
            // of the time there are just one tables.
            while (index > 0)
              {
                // Read the identifier information and class
                // information about the Huffman table, then read the
                // 16 byte codelength in and read in the Huffman values
                // and put it into table info.
                byte huffmanInfo = jpegStream.readByte();
                byte tableClass = (byte) (huffmanInfo >> 4);
                byte huffmanIndex = (byte) (huffmanInfo & 0x0f);
                short[] codeLength = new short[16];
                jpegStream.readFully(codeLength, 0, codeLength.length);
                int huffmanValueLen = 0;
                for (int i = 0; i < 16; i++)
                  huffmanValueLen += codeLength[i];
                index -= (huffmanValueLen + 17);
                short[] huffmanVal = new short[huffmanValueLen];
                for (int i = 0; i < huffmanVal.length; i++)
                  huffmanVal[i] = jpegStream.readByte();
                // Assign DC Huffman Table.
                if (tableClass == HuffmanTable.JPEG_DC_TABLE)
                  dcTables[(int) huffmanIndex] = new JPEGHuffmanTable(codeLength,
                                                                      huffmanVal);
                // Assign AC Huffman Table.
                else if (tableClass == HuffmanTable.JPEG_AC_TABLE)
                  acTables[(int) huffmanIndex] = new JPEGHuffmanTable(codeLength,
                                                                      huffmanVal);
              }
            break;
          case JPEGMarker.DQT:
            // DQT non-SOF Marker - This defines the quantization
            // coeffecients, this allows us to figure out the quality of
            // compression and unencode the data. The data is loaded and
            // then stored in to an array.
            short quantizationLength = (short) (jpegStream.readShort() - 2);
            for (int j = 0; j < quantizationLength / 65; j++)
              {
                byte quantSpecs = jpegStream.readByte();
                int[] quantData = new int[64];
                if ((byte) (quantSpecs >> 4) == 0)
                  // Precision 8 bit.
                  {
                    for (int i = 0; i < 64; i++)
                      quantData[i] = jpegStream.readByte();
                  
                  }
                else if ((byte) (quantSpecs >> 4) == 1)
                  // Precision 16 bit.
                  {
                    for (int i = 0; i < 64; i++)
                      quantData[i] = jpegStream.readShort();
                  }
                qTables[(int) (quantSpecs & 0x0f)] = new JPEGQTable (quantData);
              }
            break;
          case JPEGMarker.SOS:
            // SOS non-SOF Marker - Start Of Scan Marker, this is where the
            // actual data is stored in a interlaced or non-interlaced with
            // from 1-4 components of color data, if three components most
            // likely a YCrCb model, this is a fairly complex process.

            // Read in the scan length.
            jpegStream.readShort();
            // Number of components in the scan.
            byte numberOfComponents = jpegStream.readByte();
            byte[] componentSelector = new byte[numberOfComponents];
            for (int i = 0; i < numberOfComponents; i++)
              {
                // Component ID, packed byte containing the Id for the
                // AC table and DC table.
                byte componentID = jpegStream.readByte();
                byte tableInfo = jpegStream.readByte();
                frame.setHuffmanTables(componentID,
                                       acTables[(byte) (tableInfo >> 4)],
                                       dcTables[(byte) (tableInfo & 0x0f)]);
                componentSelector[i] = componentID;
              }
            byte startSpectralSelection = jpegStream.readByte();
            byte endSpectralSelection = jpegStream.readByte();
            byte successiveApproximation = jpegStream.readByte();

            int mcuIndex = 0; 
            int mcuTotalIndex = 0;
            // This loops through until a MarkerTagFound exception is
            // found, if the marker tag is a RST (Restart Marker) it
            // simply skips it and moves on this system does not handle
            // corrupt data streams very well, it could be improved by
            // handling misplaced restart markers.
            while (true)
              {
                try
                  {
                    // Loop though capturing MCU, instruct each
                    // component to read in its necessary count, for
                    // scaling factors the components automatically
                    // read in how much they need
                    for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
                      {
                        JPEGComponent comp = (JPEGComponent) frame.components.getComponentByID(componentSelector[compIndex]);
                        comp.readComponentMCU(jpegStream);
                      }
                    mcuIndex++;
                    mcuTotalIndex++;
                  }
                // We've found a marker, see if the marker is a restart
                // marker or just the next marker in the stream. If
                // it's the next marker in the stream break out of the
                // while loop, if it's just a restart marker skip it
                catch (JPEGMarkerFoundException bse)
                  {
                    // Handle JPEG Restart Markers, this is where the
                    // count of MCU's per interval is compared with
                    // the count actually obtained, if it's short then
                    // pad on some MCU's ONLY for components that are
                    // greater than one. Also restart the DC prediction
                    // to zero.
                    if (marker == JPEGMarker.RST0
                        || marker == JPEGMarker.RST1
                        || marker == JPEGMarker.RST2
                        || marker == JPEGMarker.RST3
                        || marker == JPEGMarker.RST4
                        || marker == JPEGMarker.RST5
                        || marker == JPEGMarker.RST6
                        || marker == JPEGMarker.RST7)
                      {
                        for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
                          {
                            JPEGComponent comp = (JPEGComponent) frame.components.getComponentByID(componentSelector[compIndex]);
                            if (compIndex > 1)
                              comp.padMCU(mcuTotalIndex, resetInterval - mcuIndex);
                            comp.resetInterval();
                          }
                        mcuTotalIndex += (resetInterval - mcuIndex);
                        mcuIndex = 0;
                      }
                    else
                      {
                        // We're at the end of our scan, exit out.
                        break;
                      }
                  }
              }
            break;
          case JPEGMarker.DRI:
            // DRI - This defines the restart interval, if we have a
            // restart interval when we reach our restart modulo calculate
            // whether the count of MCU's specified in the restart
            // interval have been reached, if they havent then pad with
            // whatever MCU was last used, this is supposed to be a form of
            // error recovery but it turns out that some JPEG encoders
            // purposely cause missing MCU's on repeating MCU's to compress
            // data even more (even though it adds an extra layer of
            // complexity.. But since when is JPEG easy?
            jpegStream.skipBytes(2);
            resetInterval = jpegStream.readShort();
            break;
          case JPEGMarker.COM:
            // COM - This is a comment that was inserted into the JPEG, we
            // simply skip over the comment because it's really of no
            // importance, usually contains a verbal description of the
            // application or author who created the JPEG.
            jpegStream.skipBytes(jpegStream.readShort() - 2);
            break;
          case JPEGMarker.DNL:
            // DNL - This sets the height of the image. This is the Define
            // Number Lines for the image, I'm not sure exactly why we need
            // this but, whatever we'll abide.
            frame.setScanLines(jpegStream.readShort());
            break;
          case JPEGMarker.EOI:
            // EOI - End of Image, this processes the frames and turns the
            // frames into a buffered image.

            if (jpegFrames.size() == 0)
              {
                return;
              }
            else if (jpegFrames.size() == 1)
              {
                // Only one frame, JPEG Non-Heirarchial Frame.

                DCT myDCT = new DCT();
                WritableRaster raster =
                  Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
                                                 frame.width,
                                                 frame.height,
                                                 frame.getComponentCount(),
                                                 new Point(0, 0));

                // Unencode the data.
                for (int i = 0; i < frame.getComponentCount(); i++)
                  {
                    JPEGComponent comp =
                      (JPEGComponent) frame.components.get(i);
                    comp.setQuantizationTable(qTables[comp.quant_id].getTable());
                    comp.quantitizeData();
                    comp.idctData(myDCT);
                  }
                // Scale the image and write the data to the raster.
                for (int i = 0; i < frame.getComponentCount(); i++)
                  {
                    JPEGComponent comp = (JPEGComponent) frame.components.get(i);
                    comp.scaleByFactors();
                    comp.writeData(raster, i);
                    // Ensure garbage collection.
                    comp = null;
                  }
                // Grayscale Color Image (1 Component).
                if (frame.getComponentCount() == 1)
                  {
                    ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
                    ComponentColorModel ccm =
                      new ComponentColorModel(cs, false, false,
                                              Transparency.OPAQUE,
                                              DataBuffer.TYPE_BYTE);
                    image = new BufferedImage(ccm, raster, false,
                                              new Hashtable());
                  }
                // YCbCr Color Image (3 Components).
                else if (frame.getComponentCount() == 3)
                  {
                    ComponentColorModel ccm =
                      new ComponentColorModel(new YCbCr_ColorSpace(), false,
                                              false, Transparency.OPAQUE,
                                              DataBuffer.TYPE_BYTE);
                    image = new BufferedImage(ccm, raster, false,
                                              new Hashtable());
                  }
                // Possibly CMYK or RGBA ?
                else
                  {
                    throw new JPEGException("Unsupported Color Mode: 4 "
                                            + "Component Color Mode found.");
                  }
                height = frame.height;
                width = frame.width;
              }
            else
              {
                //JPEG Heirarchial Frame (progressive or baseline).
                throw new JPEGException("Unsupported Codec Type:"
                                        + " Hierarchial JPEG");
              }
            break;
          case JPEGMarker.SOF1:
            // ERROR - If we encounter any of the following marker codes
            // error out with a codec exception, progressive, heirarchial,
            // differential, arithmetic, lossless JPEG's are not supported.
            // This is where enhancements can be made for future versions.
            // Thankfully 99% of all JPEG's are baseline DCT.
            throw new JPEGException("Unsupported Codec Type: Extended "
                                    + "Sequential DCT JPEG's Not-Supported");
            //case JPEGMarker.SOF2:
            //	throw new JPEGException("Unsupported Codec Type: Progressive DCT JPEG's Not-Supported");
          case JPEGMarker.SOF3:
            throw new JPEGException("Unsupported Codec Type:"
                                    + " Lossless (sequential)");
          case JPEGMarker.SOF5:
            throw new JPEGException("Unsupported Codec Type:"
                                    + " Differential sequential DCT");
          case JPEGMarker.SOF6:
            throw new JPEGException("Unsupported Codec Type:"
                                    + " Differential progressive DCT");
          case JPEGMarker.SOF7:
            throw new JPEGException("Unsupported Codec Type:"
                                    + " Differential lossless");
          case JPEGMarker.SOF9:
          case JPEGMarker.SOF10:
          case JPEGMarker.SOF11:
          case JPEGMarker.SOF13:
          case JPEGMarker.SOF14:
          case JPEGMarker.SOF15:
            throw new JPEGException("Unsupported Codec Type:"
                                    + " Arithmetic Coding Frame");
          default:
            // Unknown marker found, ignore it.
          }
        marker = jpegStream.findNextMarker();
      }
  }

  // If the current marker is APP0, tries to decode a JFIF extension
  // and advances the current marker to the next marker in the stream.
  private void decodeJFIFExtension() throws IOException
  {
    if (marker == JPEGMarker.APP0)
      {
        int length = jpegStream.readShort();

        if (length >= JFXX_FIXED_LENGTH)
          {
            byte[] identifier = new byte[5];
            jpegStream.read(identifier);
            if (identifier[0] != JPEGMarker.JFIF_J
                || identifier[1] != JPEGMarker.JFIF_F
                || identifier[2] != JPEGMarker.JFIF_X
                || identifier[3] != JPEGMarker.JFIF_X
                || identifier[4] != JPEGMarker.X00)
              // Not a JFXX field.  Ignore it and continue.
              jpegStream.skipBytes(length - 7);
            else
              {
                byte extension_code = jpegStream.readByte();

                switch (extension_code)
                  {
                  case JPEGMarker.JFXX_JPEG:
                    // FIXME: add support for JFIF Extension:
                    // Thumbnail coded using JPEG.
                    jpegStream.skipBytes(length - 8);
                  case JPEGMarker.JFXX_ONE_BPP:
                    // FIXME: add support for JFIF Extension:
                    // Thumbnail stored using 1 byte/pixel.
                    jpegStream.skipBytes(length - 8);
                  case JPEGMarker.JFXX_THREE_BPP:
                    // FIXME: add support for JFIF Extension:
                    // Thumbnail stored using 3 bytes/pixel.
                    jpegStream.skipBytes(length - 8);
                  }
              }
          }
        else
          {
            // Unknown APP0 marker.  Ignore it and continue.
            jpegStream.skipBytes(length - 2);
          }
        marker = jpegStream.findNextMarker();
      }
  }

  public BufferedImage getImage()
  {
    return image;
  }
}
