001/*
002 * (C) Copyright 2018 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bdelbosc
018 */
019package org.nuxeo.importer.stream.consumer.watermarker;
020
021import java.io.ByteArrayOutputStream;
022import java.io.File;
023import java.io.IOException;
024import java.nio.file.Path;
025
026import org.apache.commons.imaging.ImageReadException;
027import org.apache.commons.imaging.ImageWriteException;
028import org.apache.commons.imaging.Imaging;
029import org.apache.commons.imaging.common.ImageMetadata;
030import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
031import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;
032import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
033import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;
034import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;
035import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
036import org.apache.commons.io.FileUtils;
037
038/**
039 * Adds a watermark to JPEG image by adding an exif metadata.
040 * This trivial impl load the image in memory so don't use it on big pictures.
041 * This is for testing purpose only.
042 *
043 * @since 10.2
044 */
045public class JpegWatermarker extends AbstractWatermarker {
046
047    @Override
048    public Path addWatermark(Path inputFile, Path outputDir, String watermark) {
049        File jpegImageFile = inputFile.toFile();
050        ByteArrayOutputStream os = new ByteArrayOutputStream();
051        try {
052            TiffOutputSet outputSet = null;
053            ImageMetadata metadata = Imaging.getMetadata(jpegImageFile);
054            JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
055            if (jpegMetadata != null) {
056                TiffImageMetadata exif = jpegMetadata.getExif();
057                if (exif != null) {
058                    outputSet = exif.getOutputSet();
059                }
060            }
061            if (outputSet == null) {
062                outputSet = new TiffOutputSet();
063            }
064            final TiffOutputDirectory exifDirectory = outputSet.getOrCreateRootDirectory();
065            exifDirectory.removeField(ExifTagConstants.EXIF_TAG_SOFTWARE);
066            exifDirectory.add(ExifTagConstants.EXIF_TAG_SOFTWARE, watermark);
067            new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os, outputSet);
068            os.flush();
069            File output = getOutputPath(inputFile, outputDir, watermark).toFile();
070            FileUtils.writeByteArrayToFile(output, os.toByteArray());
071            return output.toPath();
072        } catch (ImageReadException | ImageWriteException | IOException e) {
073            throw new IllegalArgumentException("Unable to edit jpeg " + inputFile, e);
074        } finally {
075            try {
076                os.close();
077            } catch (IOException e) {
078                // shade
079            }
080        }
081    }
082}