Package com.xuggle.xuggler.video

Source Code of com.xuggle.xuggler.video.ConverterFactoryTest

/*******************************************************************************
* Copyright (c) 2008, 2010 Xuggle Inc.  All rights reserved.
* This file is part of Xuggle-Xuggler-Main.
*
* Xuggle-Xuggler-Main is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xuggle-Xuggler-Main 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Xuggle-Xuggler-Main.  If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/

package com.xuggle.xuggler.video;

import java.util.Collection;
import java.util.Vector;

import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.IPixelFormat;
import com.xuggle.xuggler.IVideoResampler;
import com.xuggle.xuggler.IVideoResampler.Feature;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.util.Random;

import org.junit.*;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;


import static junit.framework.Assert.*;
import static java.lang.Math.*;

@RunWith(Parameterized.class)
public class ConverterFactoryTest
{
  // default width and height for test images, note that the width is
  // (and should remain) a perfect multiple of 16 which intentionally
  // avoids some issue with image resampling.  those issues are
  // exersized in specific tests such that can be ignored until the
  // underly cause can be estabish.

  public static final int TEST_WIDTH  = 48;
  public static final int TEST_HEIGHT = 48;

  private final ConverterFactory.Type mConverterType;
  private final IPixelFormat.Type mPixelType;

  // pixel types to included for resampling tests, as we really want
  // them to work properly
 
  public static final IPixelFormat.Type[] mIncludedPixelTypes =
  {
    IPixelFormat.Type.ARGB,   
    IPixelFormat.Type.BGR24,
    IPixelFormat.Type.YUV420P,
  };

  // pixel types to exclude from test as no resamplers exist for them,
  // if new types appear, NOTE: this list is not currently being used

  public static final IPixelFormat.Type[] mExcludePixelTypes =
  {
    IPixelFormat.Type.NONE,   
    IPixelFormat.Type.PAL8,
    IPixelFormat.Type.XVMC_MPEG2_MC,
    IPixelFormat.Type.XVMC_MPEG2_IDCT,
    IPixelFormat.Type.UYYVYY411,
    IPixelFormat.Type.BGR4,
    IPixelFormat.Type.RGB4,
    IPixelFormat.Type.NV12,
    IPixelFormat.Type.NV21,
    IPixelFormat.Type.VDPAU_H264,
    IPixelFormat.Type.VDPAU_MPEG1,
    IPixelFormat.Type.VDPAU_MPEG2,
    IPixelFormat.Type.VDPAU_WMV3,
    IPixelFormat.Type.VDPAU_VC1,
    IPixelFormat.Type.RGB48BE,
    IPixelFormat.Type.RGB48LE,
    IPixelFormat.Type.RGB565BE,
    IPixelFormat.Type.RGB555BE,
    IPixelFormat.Type.BGR565BE,
    IPixelFormat.Type.BGR555BE,
    IPixelFormat.Type.VAAPI_MOCO,
    IPixelFormat.Type.VAAPI_IDCT,
    IPixelFormat.Type.VAAPI_VLD,
    IPixelFormat.Type.NB,
  };

  public ConverterFactoryTest(ConverterFactory.Type converterType,
    IPixelFormat.Type pixelType)
  {
    mConverterType = converterType;
    mPixelType = pixelType;
    System.out.println("Testing " + mConverterType + ", " + mPixelType);
  }

  // create a parameter list of different types of converters

  @Parameters
    public static Collection<Object[]> converterTypes()
  {
    Collection<Object[]> parameters = new Vector<Object[]>();
   
    for (IPixelFormat.Type pixelType: mIncludedPixelTypes)
      for (ConverterFactory.Type converterType:
             ConverterFactory.getRegisteredConverters())
        {
          Object[] tuple = {converterType, pixelType};
          parameters.add(tuple);
        }
     
    return parameters;
  }
 
  @Test(expected=IllegalArgumentException.class)
  public void testVideoPictureToImageNullInput()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      throw new IllegalArgumentException();
   
    IConverter c = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), mConverterType.getPictureType(),
      TEST_WIDTH, TEST_HEIGHT);
   
    c.toImage(null);
  }

  @Test(expected=IllegalArgumentException.class)
  public void testImageToVideoPictureNullInput()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      throw new IllegalArgumentException();

    IConverter c = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), mConverterType.getPictureType(),
      TEST_WIDTH, TEST_HEIGHT);
   
    c.toPicture(null, 0);
  }

  @Test(expected=IllegalArgumentException.class)
  public void testVideoPictureToImageIncompletePicture()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      throw new IllegalArgumentException();

    IConverter c = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), mConverterType.getPictureType(),
      TEST_WIDTH, TEST_HEIGHT);

    IVideoPicture picture = IVideoPicture.make(
      mConverterType.getPictureType(), TEST_WIDTH, TEST_HEIGHT);

    c.toImage(picture);
  }

  @Test(expected=IllegalArgumentException.class)
  public void testVideoPictureToImageWrongFormat()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      throw new IllegalArgumentException();

    IConverter c = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), IPixelFormat.Type.YUV420P,
      TEST_WIDTH, TEST_HEIGHT);

    IVideoPicture picture = IVideoPicture.make(
      IPixelFormat.Type.GRAY16BE, TEST_WIDTH, TEST_HEIGHT);

    c.toImage(picture);
  }

  @Test(expected=IllegalArgumentException.class)
  public void testImageToVideoPictureWrongFormatInput()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      throw new IllegalArgumentException();

    IConverter c = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), IPixelFormat.Type.YUV420P,
      TEST_WIDTH, TEST_HEIGHT);

    BufferedImage image = new BufferedImage(
      TEST_WIDTH, TEST_HEIGHT, BufferedImage.TYPE_INT_RGB);

    c.toPicture(image, 0);
  }

  // this test makes user of mPixelType which, and thus the solid color
  // test attempts to test across colors spaces.

  @Test
  public void testImageToImageSolidColor()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      return;
   
    int w = TEST_WIDTH;
    int h = TEST_HEIGHT;
    int gray  = Color.GRAY.getRGB();

    // create the converter

    IConverter converter = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), mPixelType, w, h);

    // construct an all gray image

    BufferedImage image1 = new BufferedImage(
      w, h, mConverterType.getImageType());
    for (int x = 0; x < w; ++x)
      for (int y = 0; y < h; ++y)
        image1.setRGB(x, y, gray);

    // convert image1 to a picture and then back to image2

    BufferedImage image2 = converter.toImage(
      converter.toPicture(image1, 0));

    // test that all the pixels in image2 are gray, but not black or
    // white

    for (int x = 0; x < w; ++x)
      for (int y = 0; y < h; ++y)
      {
        int pixel1 = image1.getRGB(x, y);
        int pixel2 = image2.getRGB(x, y);

        String message = testPixels(
          mConverterType.getPictureType() == converter.getPictureType(),
          pixel1, pixel2, x, y,
          converter.getPictureType());
        assertNull(message, message);
      }
  }


  // this test makes user of mPixelType which, and thus the solid color
  // test attempts to test across colors spaces.

  @Test
  public void testImageToImageSolidColorWithResize()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      return;

    int w1 = TEST_WIDTH;
    int h1 = TEST_HEIGHT;
    int w2 = TEST_WIDTH * 2;
    int h2 = TEST_HEIGHT * 2;
    int gray  = Color.GRAY.getRGB();

    // create the converters

    IConverter converter1 = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), mPixelType, w2, h2, w1, h1);

    IConverter converter2 = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), mPixelType, w2, h2, w2, h2);

    // construct an all gray image

    BufferedImage image1 = new BufferedImage(
      w1, h1, mConverterType.getImageType());
    for (int x = 0; x < w1; ++x)
      for (int y = 0; y < h1; ++y)
        image1.setRGB(x, y, gray);

    // convert image1 to a picture and then back to image2

    IVideoPicture picutre = converter1.toPicture(image1, 0);
    BufferedImage image2 = converter2.toImage(picutre);

    assertEquals("image2 wrong width", w2, image2.getWidth());
    assertEquals("image2 wrong height", h2, image2.getHeight());

    // test that all the pixels in image2 are gray, but not black or
    // white

    for (int x = 0; x < w1; ++x)
      for (int y = 0; y < h1; ++y)
      {
        int pixel1 = image1.getRGB(x, y);
        int pixel2 = image2.getRGB(x * 2, y * 2);

        String message = testPixels(
          false, pixel1, pixel2, x, y,
          converter1.getPictureType());
        assertNull(message, message);
      }
  }

  // this test makes user of mPixelType which, and thus the solid color
  // test attempts to test across colors spaces.

  @Ignore @Test
  public void testImageToImageSolidColorWithCustomSizes()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      return;
   
    int w = TEST_WIDTH + 15;
    int h = TEST_HEIGHT;
    int gray  = Color.GRAY.getRGB();

    // create the converter

    IConverter converter = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), mPixelType, w, h);

    // construct an all gray image

    BufferedImage image1 = new BufferedImage(
      w, h, mConverterType.getImageType());
    for (int x = 0; x < w; ++x)
      for (int y = 0; y < h; ++y)
        image1.setRGB(x, y, gray);

    // convert image1 to a picture and then back to image2

    BufferedImage image2 = converter.toImage(
      converter.toPicture(image1, 0));

    // test that all the pixels in image2 are gray, but not black or
    // white

    for (int x = 0; x < w; ++x)
      for (int y = 0; y < h; ++y)
      {
        int pixel1 = image1.getRGB(x, y);
        int pixel2 = image2.getRGB(x, y);

        String message = testPixels(
          mConverterType.getPictureType() == converter.getPictureType(),
          pixel1, pixel2, x, y,
          converter.getPictureType());
        assertNull(message, message);
      }
  }

  @Test
  public void testImageToImageRandomColor()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      return;

    int w = TEST_WIDTH;
    int h = TEST_HEIGHT;
    Random rnd = new Random();

    // create the converter

    IConverter converter = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), mConverterType.getPictureType(),
      w, h);

    // construct an image of random colors

    BufferedImage image1 = new BufferedImage(
      w, h, mConverterType.getImageType());
    for (int x = 0; x < w; ++x)
      for (int y = 0; y < h; ++y)
      {
        Color c = new Color(rnd.nextInt(255),
          rnd.nextInt(255), rnd.nextInt(255));
        image1.setRGB(x, y, c.getRGB());
      }

    // convert image1 to a picture and then back to image2

    BufferedImage image2 = converter.toImage(
      converter.toPicture(image1, 0));

    // test that all the pixels in image2 are the same as image1

    for (int x = 0; x < w; ++x)
      for (int y = 0; y < h; ++y)
      {
        int pixel1 = image1.getRGB(x, y);
        int pixel2 = image2.getRGB(x, y);

        String message = testPixels(
          mConverterType.getPictureType() == converter.getPictureType(),
          pixel1, pixel2, x, y,
          converter.getPictureType());
        assertNull(message, message);
      }
  }

  @Test
  public void testPictureToPictureWithRotate()
  {
    if (!IVideoResampler.isSupported(Feature.FEATURE_COLORSPACECONVERSION))
      return;

    // note that the image is square in this test to make rotation
    // easier to handle

    int size = TEST_WIDTH;
    int black = Color.BLACK.getRGB();
    int white = Color.WHITE.getRGB();

    // create the converter

    IConverter converter = ConverterFactory.createConverter(
      mConverterType.getDescriptor(), mConverterType.getPictureType(),
      size, size);

    // construct an image with black and white stripped columns

    BufferedImage image1 = new BufferedImage(
      size, size, mConverterType.getImageType());
    for (int x = 0; x < size; ++x)
      for (int y = 0; y < size; ++y)
      {
        int color = x % 2 == 0 ? black : white;
        image1.setRGB(x, y, color);
      }

    // convert image1 to a picture and then back to image2

    BufferedImage image2 = converter.toImage(
      converter.toPicture(image1, 0));

    // rotae image2 into image3

    AffineTransform t = AffineTransform.getRotateInstance(
      Math.PI/2, image2.getWidth() / 2, image2.getHeight() / 2);
    AffineTransformOp ato = new AffineTransformOp(t,
      AffineTransformOp.TYPE_BICUBIC);
    BufferedImage image3 = new BufferedImage(
      size, size, mConverterType.getImageType());
    image3 = ato.filter(image2, image3);

    // convert image3 to a picture and then back to an image (4)

    BufferedImage image4 = converter.toImage(converter.toPicture(image3, 0));

    // test that image4 now contains stripped rows (not columns)

    for (int x = 0; x < size; ++x)
      for (int y = 0; y < size; ++y)
      {
        int pixel1 = y % 2 == 0 ? black : white;
        int pixel2 = image4.getRGB(x, y);

        String message = testPixels(
          mConverterType.getPictureType() == converter.getPictureType(),
          pixel1, pixel2, x, y,
          converter.getPictureType());
        assertNull(message, message);
      }
  }

  /**
   * Test two pixels, if the pixels are different, a detailed
   * description of the condition is returned, otherwise null is
   * returned.  If the pixel type matches that of the converter, the
   * pixel confirms an exact value match, otherwise it confirms that the
   * pixels are mearly fairly similar in color value.
   */

  private String testPixels(boolean exact, int pixel1, int pixel2, int x, int y,
    IPixelFormat.Type pixelType)
  {
    String message = "Color value missmatch whith pixel type " +
      pixelType + ", converter " + mConverterType +
      ", at pixel (" + x + "," + y + ").  Value is " +
      pixel2 + " but should be " + pixel1 + ".";

    // if types match, test exact pixels values

    if (exact)
      return (pixel1 == pixel2? null : message;

    // test color with margin for error

    int margin = 8;
    Color c1 = new Color(pixel1);
    Color c2 = new Color(pixel2);
    if (
      !closeEnough(c1.getRed  (), c2.getRed  (), margin) ||
      !closeEnough(c1.getGreen(), c2.getGreen(), margin) ||
      !closeEnough(c1.getBlue (), c2.getBlue (), margin))
    {
     
      System.out.println("missmatch at: (" + x + "x" + y + ")");
      System.out.println("red:   " + (c1.getRed  () ) + " vs. " + (c2.getRed  () ));
      System.out.println("green: " + (c1.getGreen() ) + " vs. " + (c2.getGreen() ));
      System.out.println("blue:  " + (c1.getBlue () ) + " vs. " + (c2.getBlue () ));

      return message;
    }
   
    // pixels are close enough

    return null;
  }

  private static boolean closeEnough(int v1, int v2, int margin)
  {
    return abs(v2 - v1) <= margin;
  }
}
TOP

Related Classes of com.xuggle.xuggler.video.ConverterFactoryTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.