<commit_before>/*
 * $Id$
 *
 * Copyright (c) 2009-2013 by <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, copies are available
 * at http://www.opensource.org.
 */

package VASSAL.tools.image;

import java.awt.Dimension;
import java.awt.color.CMMException;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;

import VASSAL.tools.io.IOUtils;
import VASSAL.tools.io.RereadableInputStream;
import VASSAL.tools.lang.Reference;

/**
 * An image loader which wraps {@link ImageIO}.
 *
 * This class handles the assorted problems with various versions of
 * {@link ImageIO}, ensuring that we can reliably load image files to
 * {@link BufferedImages} with a predictable type.
 *
 * @since 3.1.0
 * @author <NAME>
 */
public class ImageIOImageLoader implements ImageLoader {

  protected final ImageTypeConverter tconv;

  /**
   * Create an image loader.
   *
   * @param tconv the <code>ImageTypeConverter</code> to use for type
   * conversions
   */
  public ImageIOImageLoader(ImageTypeConverter tconv) {
    this.tconv = tconv;
  }

  // Used to indicate whether this version of Java has the PNG iTXt bug.
  // This can be removed once we no longer support Java 1.5.
  protected static final boolean iTXtBug;

  static {
    final String jvmver = System.getProperty("java.version");
    iTXtBug = jvmver == null || jvmver.startsWith("1.5");
  }

  protected static final Set<Integer> skip_iTXt =
    Collections.singleton(PNGDecoder.iTXt);

  // Used to indicate whether this version of Java has the JPEG color
  // correction bug.
  protected static final boolean YCbCrBug;

  static {
    BufferedImage img = null;

    InputStream in = null;
    try {
      // We intentionally bypass the normal image loading system
      // in order to see how ImageIO loads the test image.
      in = ImageIOImageLoader.class.getResourceAsStream("/images/black.jpg");
      img = ImageIO.read(new MemoryCacheImageInputStream(in));
      in.close();
    }
    catch (IOException e) {
      // this should not happen
      throw new IllegalStateException();
    }
    finally {
      IOUtils.closeQuietly(in);
    }

    if (img == null) {
      // this should not happen
      throw new IllegalStateException();
    }

    // The pixel in the image is supposed to be black. If the pixel is
    // green, then ImageIO is misinterpreting the YCbCr data as RGB.
    final int pixel = img.getRGB(0,0);
    switch (pixel) {
    case 0xFF000000:
      YCbCrBug = false;
      break;
    case 0xFF008700:
      YCbCrBug = true;
      break;
    default:
      // This JVM is broken in an unexpected way!
      throw new IllegalStateException(
        "Unexpected pixel value 0x" + String.format("%08x", pixel)
      );
    }
  }

  /**
   * Loads an image.
   *
   * @param name the image name
   * @param in the input stream<commit_msg>Bug 10723: Don't throw if the black pixel is read as 0xFF008080, in order to let people with this bug load a test module.<commit_after>/*
 * $Id$
 *
 * Copyright (c) 2009-2013 by <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, copies are available
 * at http://www.opensource.org.
 */

package VASSAL.tools.image;

import java.awt.Dimension;
import java.awt.color.CMMException;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;

import VASSAL.tools.io.IOUtils;
import VASSAL.tools.io.RereadableInputStream;
import VASSAL.tools.lang.Reference;

/**
 * An image loader which wraps {@link ImageIO}.
 *
 * This class handles the assorted problems with various versions of
 * {@link ImageIO}, ensuring that we can reliably load image files to
 * {@link BufferedImages} with a predictable type.
 *
 * @since 3.1.0
 * @author <NAME>
 */
public class ImageIOImageLoader implements ImageLoader {

  protected final ImageTypeConverter tconv;

  /**
   * Create an image loader.
   *
   * @param tconv the <code>ImageTypeConverter</code> to use for type
   * conversions
   */
  public ImageIOImageLoader(ImageTypeConverter tconv) {
    this.tconv = tconv;
  }

  // Used to indicate whether this version of Java has the PNG iTXt bug.
  // This can be removed once we no longer support Java 1.5.
  protected static final boolean iTXtBug;

  static {
    final String jvmver = System.getProperty("java.version");
    iTXtBug = jvmver == null || jvmver.startsWith("1.5");
  }

  protected static final Set<Integer> skip_iTXt =
    Collections.singleton(PNGDecoder.iTXt);

  // Used to indicate whether this version of Java has the JPEG color
  // correction bug.
  protected static final boolean YCbCrBug;

  static {
    BufferedImage img = null;

    InputStream in = null;
    try {
      // We intentionally bypass the normal image loading system
      // in order to see how ImageIO loads the test image.
      in = ImageIOImageLoader.class.getResourceAsStream("/images/black.jpg");
      img = ImageIO.read(new MemoryCacheImageInputStream(in));
      in.close();
    }
    catch (IOException e) {
      // this should not happen
      throw new IllegalStateException();
    }
    finally {
      IOUtils.closeQuietly(in);
    }

    if (img == null) {
      // this should not happen
      throw new IllegalStateException();
    }

    // The pixel in the image is supposed to be black. If the pixel is
    // green, then ImageIO is misinterpreting the YCbCr data as RGB.
    final int pixel = img.getRGB(0,0);
    switch (pixel) {
    case 0xFF000000:
    case 0xFF008080:
      YCbCrBug = false;
      break;
    case 0xFF008700:
      YCbCrBug = true;
      break;
    default:
      // This JVM is broken in an unexpected way!
      throw new IllegalStateException(
        "Unexpected pixel value 0x" + String.format("%08x", pixel)
      );
    }
  }

  /**
   * Loads an image.
   *
   * @param name the image name
   * @param in the input stream
{'fraction_non_alphanumeric': 0.08615425461303597, 'fraction_numerical': 0.011549183592194345, 'mean_word_length': 3.1878821567537523, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1452117', 'n_tokens_mistral': 2257, 'n_tokens_neox': 2160, 'n_words': 802}