From 7f2ad302f51f632faef7432e7cd9e8b790661a6b Mon Sep 17 00:00:00 2001 From: Werner Randelshofer Date: Fri, 9 Aug 2024 13:44:57 +0200 Subject: [PATCH] Use InputStream.transferTo method. --- .../org/monte/media/io/IOStreams.java | 20 ------- .../monte/media/jpeg/CMYKJPEGImageReader.java | 3 +- .../org/monte/media/mjpg/MJPGImageReader.java | 2 +- .../quicktime/QuickTimeOutputStream.java | 45 ++++++--------- .../media/quicktime/QuickTimeWriter.java | 57 +++++++------------ 5 files changed, 41 insertions(+), 86 deletions(-) diff --git a/org.monte.media/src/main/java/org.monte.media/org/monte/media/io/IOStreams.java b/org.monte.media/src/main/java/org.monte.media/org/monte/media/io/IOStreams.java index dd83c0d..11c756c 100755 --- a/org.monte.media/src/main/java/org.monte.media/org/monte/media/io/IOStreams.java +++ b/org.monte.media/src/main/java/org.monte.media/org/monte/media/io/IOStreams.java @@ -8,7 +8,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.StandardCopyOption; @@ -29,25 +28,6 @@ public static void copy(File source, File target) throws IOException { Files.copy(source.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); } - /** - * Copies the remainder of the source stream into the provided target - * stream. - * - * @param source the source stream - * @param target the target stream - * @return number of copied bytes - * @throws IOException if an I/O error occurs - */ - public static long copy(InputStream source, OutputStream target) throws IOException { - long n = 0L; - byte[] b = new byte[8192]; - for (int count = source.read(b); count != -1; count = source.read(b)) { - target.write(b, 0, count); - n += count; - } - return n; - } - /** * Copies the remainder of the source stream into the provided target * stream. diff --git a/org.monte.media/src/main/java/org.monte.media/org/monte/media/jpeg/CMYKJPEGImageReader.java b/org.monte.media/src/main/java/org.monte.media/org/monte/media/jpeg/CMYKJPEGImageReader.java index 39d3998..76f24d8 100755 --- a/org.monte.media/src/main/java/org.monte.media/org/monte/media/jpeg/CMYKJPEGImageReader.java +++ b/org.monte.media/src/main/java/org.monte.media/org/monte/media/jpeg/CMYKJPEGImageReader.java @@ -6,7 +6,6 @@ import org.monte.media.image.CMYKImages; import org.monte.media.io.ByteArrayImageInputStream; -import org.monte.media.io.IOStreams; import org.monte.media.io.ImageInputStreamAdapter; import org.monte.media.jfif.JFIFInputStream; @@ -225,7 +224,7 @@ public static BufferedImage read(ImageInputStream in, boolean inverseYCCKColors, // Read Adobe ICC_PROFILE int buffer. The profile is split up over // multiple APP2 marker segments. - IOStreams.copy(dis, app2ICCProfile); + dis.transferTo(app2ICCProfile); } } } else if (seg.marker == 0xffee) { diff --git a/org.monte.media/src/main/java/org.monte.media/org/monte/media/mjpg/MJPGImageReader.java b/org.monte.media/src/main/java/org.monte.media/org/monte/media/mjpg/MJPGImageReader.java index cda86a8..4ffbb85 100755 --- a/org.monte.media/src/main/java/org.monte.media/org/monte/media/mjpg/MJPGImageReader.java +++ b/org.monte.media/src/main/java/org.monte.media/org/monte/media/mjpg/MJPGImageReader.java @@ -24,7 +24,7 @@ /** * Reads an image in the Motion JPEG (MJPG) format. *

- * . This class can read Motion JPEG files with omitted Huffmann table. + * This class can read Motion JPEG files with omitted Huffmann table. *

* For more information see: Microsoft Windows Bitmap Format. Multimedia * Technical Note: JPEG DIB Format. (c) 1993 Microsoft Corporation. All rights diff --git a/org.monte.media/src/main/java/org.monte.media/org/monte/media/quicktime/QuickTimeOutputStream.java b/org.monte.media/src/main/java/org.monte.media/org/monte/media/quicktime/QuickTimeOutputStream.java index d632e85..cc582ba 100755 --- a/org.monte.media/src/main/java/org.monte.media/org/monte/media/quicktime/QuickTimeOutputStream.java +++ b/org.monte.media/src/main/java/org.monte.media/org/monte/media/quicktime/QuickTimeOutputStream.java @@ -5,8 +5,6 @@ package org.monte.media.quicktime; import org.monte.media.av.Format; -import org.monte.media.av.FormatKeys.MediaType; -import org.monte.media.io.IOStreams; import org.monte.media.io.ImageOutputStreamAdapter; import org.monte.media.math.Rational; @@ -29,6 +27,7 @@ import static org.monte.media.av.FormatKeys.EncodingKey; import static org.monte.media.av.FormatKeys.FrameRateKey; import static org.monte.media.av.FormatKeys.MIME_QUICKTIME; +import static org.monte.media.av.FormatKeys.MediaType; import static org.monte.media.av.FormatKeys.MediaTypeKey; import static org.monte.media.av.FormatKeys.MimeTypeKey; import static org.monte.media.av.codec.audio.AudioFormatKeys.ByteOrderKey; @@ -350,7 +349,7 @@ public int addAudioTrack(String compressionType, // * encoded with lossless encoders such as the PNG format.

The default * value is 0.97. * - * @param newValue + * @param newValue the new value */ public void setCompressionQuality(int track, float newValue) { VideoTrack vt = (VideoTrack) tracks.get(track); @@ -374,14 +373,14 @@ public float getCompressionQuality(int track) { * write all samples as sync samples. n = sync every n-th sample. */ public void setSyncInterval(int track, int i) { - ((VideoTrack) tracks.get(track)).syncInterval = i; + tracks.get(track).syncInterval = i; } /** * Gets the sync interval from the specified video track. */ public int getSyncInterval(int track) { - return ((VideoTrack) tracks.get(track)).syncInterval; + return tracks.get(track).syncInterval; } /** @@ -653,7 +652,7 @@ public void writeSample(int track, InputStream in, long duration, boolean isSync ensureStarted(); long offset = getRelativeStreamPosition(); OutputStream mdatOut = mdatAtom.getOutputStream(); - IOStreams.copy(in, mdatOut); + in.transferTo(mdatOut); long length = getRelativeStreamPosition() - offset; t.addSample(new Sample(duration, offset, length), 1, isSync); } @@ -1018,10 +1017,8 @@ private void writeEpilog() throws IOException { } // Optional color table atom - for (int i = 0, n = tracks.size(); i < n; i++) { - Track t = tracks.get(i); - if (t instanceof VideoTrack) { - VideoTrack vt = (VideoTrack) t; + for (Track t : tracks) { + if (t instanceof VideoTrack vt) { if (vt.videoColorTable != null) { vt.writeColorTableAtom(moovAtom); break; @@ -1158,10 +1155,10 @@ protected void writeTrackAtoms(int trackIndex, CompositeAtom moovAtom, Date modi // See Figure 2-8 for an illustration of a matrix structure: // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap2/chapter_3_section_3.html#//apple_ref/doc/uid/TP40000939-CH204-32967 - d.writeFixed16D16(t.mediaType == MediaType.VIDEO ? ((VideoTrack) t).width : 0); // width + d.writeFixed16D16(t.mediaType == MediaType.VIDEO ? t.width : 0); // width // A 32-bit fixed-point number that specifies the width of this track in pixels. - d.writeFixed16D16(t.mediaType == MediaType.VIDEO ? ((VideoTrack) t).height : 0); // height + d.writeFixed16D16(t.mediaType == MediaType.VIDEO ? t.height : 0); // height // A 32-bit fixed-point number that indicates the height of this track in pixels. /* Edit Atom ========= */ @@ -1202,10 +1199,10 @@ protected void writeTrackAtoms(int trackIndex, CompositeAtom moovAtom, Date modi d.writeFixed16D16(1); // mediaRate } else { d.writeUInt(elist.length); // numberOfEntries - for (int i = 0; i < elist.length; ++i) { - d.writeUInt(elist[i].trackDuration); // trackDuration - d.writeUInt(elist[i].mediaTime); // mediaTime - d.writeUInt(elist[i].mediaRate); // mediaRate + for (Edit edit : elist) { + d.writeUInt(edit.trackDuration); // trackDuration + d.writeUInt(edit.mediaTime); // mediaTime + d.writeUInt(edit.mediaRate); // mediaRate } } @@ -1265,7 +1262,7 @@ protected void writeTrackAtoms(int trackIndex, CompositeAtom moovAtom, Date modi // A 16-bit integer that specifies the media’s playback quality—that is, // its suitability for playback in a given environment. - /** + /* * Media Handler Reference Atom ------- */ leaf = new DataAtom("hdlr"); @@ -1336,14 +1333,9 @@ protected void writeMediaInformationAtoms(int trackIndex, CompositeAtom mdiaAtom /* Video or Audio media information atom -------- */ switch (t.mediaType) { - case VIDEO: - writeVideoMediaInformationHeaderAtom(trackIndex, minfAtom); - break; - case AUDIO: - writeSoundMediaInformationHeaderAtom(trackIndex, minfAtom); - break; - default: - throw new UnsupportedOperationException("Media type " + t.mediaType + " not supported yet."); + case VIDEO -> writeVideoMediaInformationHeaderAtom(trackIndex, minfAtom); + case AUDIO -> writeSoundMediaInformationHeaderAtom(trackIndex, minfAtom); + default -> throw new UnsupportedOperationException("Media type " + t.mediaType + " not supported yet."); } @@ -1920,7 +1912,7 @@ public void toWebOptimizedMovie(File outputFile, boolean compressHeader) throws } } - if (maxIteration < 0 || buf.size() == 0) { + if (buf.size() == 0) { compressHeader = false; System.err.println("WARNING QuickTimeWriter failed to compress header."); } else { @@ -1952,7 +1944,6 @@ public void toWebOptimizedMovie(File outputFile, boolean compressHeader) throws daos.write(0); } } - } if (!compressHeader) { out = new FileImageOutputStream(outputFile); diff --git a/org.monte.media/src/main/java/org.monte.media/org/monte/media/quicktime/QuickTimeWriter.java b/org.monte.media/src/main/java/org.monte.media/org/monte/media/quicktime/QuickTimeWriter.java index 5f2d53d..e0f7948 100755 --- a/org.monte.media/src/main/java/org.monte.media/org/monte/media/quicktime/QuickTimeWriter.java +++ b/org.monte.media/src/main/java/org.monte.media/org/monte/media/quicktime/QuickTimeWriter.java @@ -264,7 +264,6 @@ public int addTrack(Format fmt) throws IOException { * @throws IllegalArgumentException if the width or the height is smaller * than 1. */ - @Deprecated public int addVideoTrack(Format format, long timeScale, int width, int height) throws IOException { return addVideoTrack(format.get(EncodingKey), format.get(CompressorNameKey), timeScale, width, height, 24, 30); } @@ -279,7 +278,6 @@ public int addVideoTrack(Format format, long timeScale, int width, int height) t * @throws IllegalArgumentException if the width or the height is smaller * than 1. */ - @Deprecated public int addVideoTrack(Format format, int width, int height, int depth, int syncInterval) throws IOException { return addVideoTrack(format.get(EncodingKey), format.get(CompressorNameKey), format.get(FrameRateKey).getDenominator() * format.get(FrameRateKey).getNumerator(), width, height, depth, syncInterval); } @@ -294,7 +292,6 @@ public int addVideoTrack(Format format, int width, int height, int depth, int sy * @param format The javax.sound audio format. * @return Returns the track index. */ - @Deprecated public int addAudioTrack(javax.sound.sampled.AudioFormat format) throws IOException { ensureStarted(); String qtAudioFormat; @@ -314,45 +311,33 @@ public int addAudioTrack(javax.sound.sampled.AudioFormat format) throws IOExcept throw new IllegalArgumentException("Sample size of 8 for ALAW required:" + sampleSizeInBits); } } else if (javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED.equals(enc)) { - switch (sampleSizeInBits) { - case 8:// Requires conversion to PCM_UNSIGNED! - qtAudioFormat = "raw "; - break; - case 16: - qtAudioFormat = (byteOrder == ByteOrder.BIG_ENDIAN) ? "twos" : "sowt"; - break; - case 24: - qtAudioFormat = "in24"; - break; - case 32: - qtAudioFormat = "in32"; - break; - default: - throw new IllegalArgumentException("Unsupported sample size for PCM_SIGNED:" + sampleSizeInBits); - } + qtAudioFormat = switch (sampleSizeInBits) { + case 8 ->// Requires conversion to PCM_UNSIGNED! + "raw "; + case 16 -> (byteOrder == ByteOrder.BIG_ENDIAN) ? "twos" : "sowt"; + case 24 -> "in24"; + case 32 -> "in32"; + default -> + throw new IllegalArgumentException("Unsupported sample size for PCM_SIGNED:" + sampleSizeInBits); + }; } else if (javax.sound.sampled.AudioFormat.Encoding.PCM_UNSIGNED.equals(enc)) { - switch (sampleSizeInBits) { - case 8: - qtAudioFormat = "raw "; - break; - case 16:// Requires conversion to PCM_SIGNED! - qtAudioFormat = (byteOrder == ByteOrder.BIG_ENDIAN) ? "twos" : "sowt"; - break; - case 24:// Requires conversion to PCM_SIGNED! - qtAudioFormat = "in24"; - break; - case 32:// Requires conversion to PCM_SIGNED! - qtAudioFormat = "in32"; - break; - default: - throw new IllegalArgumentException("Unsupported sample size for PCM_UNSIGNED:" + sampleSizeInBits); - } + qtAudioFormat = switch (sampleSizeInBits) { + case 8 -> "raw "; + case 16 ->// Requires conversion to PCM_SIGNED! + (byteOrder == ByteOrder.BIG_ENDIAN) ? "twos" : "sowt"; + case 24 ->// Requires conversion to PCM_SIGNED! + "in24"; + case 32 ->// Requires conversion to PCM_SIGNED! + "in32"; + default -> + throw new IllegalArgumentException("Unsupported sample size for PCM_UNSIGNED:" + sampleSizeInBits); + }; } else if (javax.sound.sampled.AudioFormat.Encoding.ULAW.equals(enc)) { if (sampleSizeInBits != 8) { throw new IllegalArgumentException("Sample size of 8 for ULAW required:" + sampleSizeInBits); } qtAudioFormat = "ulaw"; - } else if ("MP3".equals(enc == null ? null : enc.toString())) { + } else if ("MP3".equals(enc.toString())) { qtAudioFormat = ".mp3"; } else { qtAudioFormat = format.getEncoding().toString();