    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.imaging.common;
    018
    019import java.io.ByteArrayOutputStream;
    020import java.io.IOException;
    021import java.util.zip.DataFormatException;
    022import java.util.zip.DeflaterOutputStream;
    023import java.util.zip.Inflater;
    024
    025import org.apache.commons.imaging.ImagingException;
    026
    027/**
    028 * <p>
    029 * Utility class to compress/decompress bytes using the ZLIB deflate/inflate compression.
    030 * </p>
    031 *
    032 * <p>
    033 * <a href="https://www.ietf.org/rfc/rfc1951.txt">RFC 1951 - DEFLATE Compressed Data Format Specification version 1.3</a>
    034 * </p>
    035 */
    036public final class ZlibDeflate {
    037
    038    /**
    039     * Compress the byte[] using ZLIB deflate compression.
    040     *
    041     * @param bytes The bytes to compress
    042     * @return The compressed bytes.
    043     * @throws ImagingException if the bytes could not be compressed.
    044     * @see DeflaterOutputStream
    045     */
    046    public static byte[] compress(final byte[] bytes) throws ImagingException {
    047        final ByteArrayOutputStream out = new ByteArrayOutputStream(Allocator.checkByteArray(bytes.length / 2));
    048        try (DeflaterOutputStream compressOut = new DeflaterOutputStream(out)) {
    049            compressOut.write(bytes);
    050        } catch (final IOException e) {
    051            throw new ImagingException("Unable to compress image", e);
    052        }
    053        return out.toByteArray();
    054    }
    055
    056    /**
    057     * Compress the byte[] using ZLIB deflate decompression.
    058     *
    059     * @param bytes        The bytes to decompress
    060     * @param expectedSize The expected size of the decompressed byte[].
    061     * @return The decompressed bytes.
    062     * @throws ImagingException if the bytes could not be decompressed.
    063     * @see Inflater
    064     */
    065    public static byte[] decompress(final byte[] bytes, final int expectedSize) throws ImagingException {
    066        try {
    067            final Inflater inflater = new Inflater();
    068            inflater.setInput(bytes);
    069            final byte[] result = Allocator.byteArray(expectedSize);
    070            inflater.inflate(result);
    071            return result;
    072        } catch (final DataFormatException e) {
    073            throw new ImagingException("Unable to decompress image", e);
    074        }
    075    }
    076
    077    private ZlibDeflate() {
    078        // empty
    079    }
    080}