| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.commons.imaging.formats.bmp; |
| |
| import java.awt.image.BufferedImage; |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Random; |
| |
| import org.apache.commons.imaging.ImageFormat; |
| import org.apache.commons.imaging.ImageReadException; |
| import org.apache.commons.imaging.ImageWriteException; |
| import org.apache.commons.imaging.Sanselan; |
| import org.apache.commons.imaging.util.Debug; |
| import org.apache.commons.imaging.util.IoUtils; |
| |
| public class BmpRoundtripTest extends BmpBaseTest |
| { |
| |
| private int[][] getSimpleRawData(int width, int height, int value) |
| { |
| int[][] result = new int[height][width]; |
| for (int y = 0; y < height; y++) |
| for (int x = 0; x < width; x++) |
| result[y][x] = value; |
| return result; |
| } |
| |
| private int[][] getAscendingRawData(int width, int height) |
| { |
| int[][] result = new int[height][width]; |
| for (int y = 0; y < height; y++) |
| for (int x = 0; x < width; x++) |
| { |
| int alpha = (x + y) % 256; |
| int value = (x + y) % 256; |
| int argb = (0xff & alpha) << 24 | (0xff & value) << 16 |
| | (0xff & value) << 8 | (0xff & value) << 0; |
| |
| result[y][x] = argb; |
| } |
| return result; |
| } |
| |
| private int[][] randomRawData(int width, int height) |
| { |
| Random random = new Random(); |
| int[][] result = new int[height][width]; |
| for (int y = 0; y < height; y++) |
| for (int x = 0; x < width; x++) |
| { |
| int argb = random.nextInt(); |
| result[y][x] = argb; |
| } |
| return result; |
| } |
| |
| public void testSmallBlackPixels() throws Exception |
| { |
| int[][] smallBlackPixels = getSimpleRawData(256, 256, 0); |
| writeAndReadImageData(smallBlackPixels); |
| } |
| |
| public void testSingleBlackPixel() throws Exception |
| { |
| int[][] singleBlackPixel = getSimpleRawData(1, 1, 0); |
| writeAndReadImageData(singleBlackPixel); |
| } |
| |
| |
| public void testSmallRedPixels() throws Exception |
| { |
| int[][] smallRedPixels = getSimpleRawData(256, 256, 0xffff0000); |
| writeAndReadImageData(smallRedPixels); |
| } |
| |
| public void testSingleRedPixel() throws Exception |
| { |
| int[][] singleRedPixel = getSimpleRawData(1, 1, 0xffff0000); |
| writeAndReadImageData(singleRedPixel); |
| } |
| |
| public void testSmallAscendingPixels() throws Exception |
| { |
| int[][] smallAscendingPixels = getAscendingRawData(256, 256); |
| writeAndReadImageData(smallAscendingPixels); |
| } |
| |
| public void testSmallRandomPixels() throws Exception |
| { |
| int[][] smallRandomPixels = randomRawData(256, 256); |
| writeAndReadImageData(smallRandomPixels); |
| } |
| |
| private BufferedImage imageDataToBufferedImage(int[][] rawData) |
| { |
| int width = rawData[0].length; |
| int height = rawData.length; |
| BufferedImage image = new BufferedImage(width, height, |
| BufferedImage.TYPE_INT_ARGB); |
| for (int y = 0; y < height; y++) |
| for (int x = 0; x < width; x++) |
| { |
| image.setRGB(x, y, rawData[y][x]); |
| } |
| return image; |
| } |
| |
| private int[][] bufferedImageToImageData(BufferedImage image) |
| { |
| int width = image.getWidth(); |
| int height = image.getHeight(); |
| int[][] result = new int[height][width]; |
| |
| for (int y = 0; y < height; y++) |
| for (int x = 0; x < width; x++) |
| { |
| result[y][x] = image.getRGB(x, y); |
| } |
| return result; |
| } |
| |
| private void writeAndReadImageData(int[][] rawData) throws IOException, |
| ImageReadException, ImageWriteException |
| { |
| BufferedImage srcImage = imageDataToBufferedImage(rawData); |
| |
| Map writeParams = new HashMap(); |
| // writeParams.put(SanselanConstants.PARAM_KEY_FORMAT, |
| // ImageFormat.IMAGE_FORMAT_BMP); |
| // writeParams.put(PngConstants.PARAM_KEY_BMP_FORCE_TRUE_COLOR, |
| // Boolean.TRUE); |
| |
| byte bytes[] = Sanselan.writeImageToBytes(srcImage, |
| ImageFormat.IMAGE_FORMAT_BMP, writeParams); |
| |
| // Debug.debug("bytes", bytes); |
| |
| File tempFile = createTempFile("temp", ".bmp"); |
| IoUtils.writeToFile(bytes, tempFile); |
| |
| BufferedImage dstImage = Sanselan.getBufferedImage(bytes); |
| |
| assertNotNull(dstImage); |
| assertTrue(srcImage.getWidth() == dstImage.getWidth()); |
| assertTrue(srcImage.getHeight() == dstImage.getHeight()); |
| |
| int dstData[][] = bufferedImageToImageData(dstImage); |
| compare(rawData, dstData); |
| } |
| |
| private void compare(int[][] a, int[][] b) |
| { |
| assertNotNull(a); |
| assertNotNull(b); |
| assertTrue(a.length == b.length); |
| |
| for (int y = 0; y < a.length; y++) |
| { |
| assertTrue(a[y].length == b[y].length); |
| // make sure row lengths consistent. |
| assertTrue(a[0].length == b[y].length); |
| for (int x = 0; x < a[y].length; x++) |
| { |
| // ignore alpha channel - BMP has no transparency. |
| int rgbA = 0xffffff & a[y][x]; |
| int rgbB = 0xffffff & b[y][x]; |
| |
| if (rgbA != rgbB) |
| { |
| Debug.debug("x: " + x + ", y: " + y + ", rgbA: " + rgbA |
| + " (0x" + Integer.toHexString(rgbA) + ")" |
| + ", rgbB: " + rgbB + " (0x" |
| + Integer.toHexString(rgbB) + ")"); |
| } |
| assertTrue(rgbA == rgbB); |
| } |
| } |
| } |
| |
| } |