/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.image.jni; import java.io.FileDescriptor; import java.io.IOException; import java.io.RandomAccessFile; import java.lang.reflect.Field; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import javax.imageio.stream.FileImageInputStream; import javax.imageio.stream.FileImageOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class FileStreamSegment extends StreamSegment { private static final Logger LOGGER = LoggerFactory.getLogger(FileStreamSegment.class); private final RandomAccessFile file; private final int fileID; FileStreamSegment(RandomAccessFile fdes, int fileID, long[] startPos, int[] length) { super(startPos, length); this.file = fdes; this.fileID = fileID; } public RandomAccessFile getFile() { return file; } public int getFileID() { return fileID; } public static int getFileIDfromFileDescriptor(FileDescriptor fileDS) { if (fileDS != null && fileDS.valid()) { try { Field fid = FileDescriptor.class.getDeclaredField("fd"); if (fid != null) { fid.setAccessible(true); return fid.getInt(fileDS); } } catch (Exception e) { if (LOGGER.isDebugEnabled()) { LOGGER.error("getFileIDfromFileDescriptor exception", e); //$NON-NLS-1$ } else { LOGGER.error(e.getMessage()); } } } // not valid id return -1; } @Override public ByteBuffer getDirectByteBuffer(int segment) throws IOException { if (segPosition == null || segPosition.length <= segment || segLength == null || segLength.length <= segment) { throw new IllegalArgumentException("Invalid position of the file to read!"); } MappedByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, segPosition[segment], segLength[segment]); // For performance reason, native order is preferred. buffer.order(ByteOrder.nativeOrder()); return buffer; } @Override public ByteBuffer getDirectByteBuffer(int startSeg, int endSeg) throws IOException { if (segPosition == null || segPosition.length <= endSeg || segLength == null || segLength.length <= endSeg) { throw new IllegalArgumentException("Invalid position of the file to read!"); } int length = segLength[startSeg]; // DICOM PS 3.5.8.2 Handle frame with multiple fragments if (startSeg < endSeg) { for (int i = startSeg + 1; i <= endSeg; i++) { length += segLength[i]; } ByteBuffer buffer = ByteBuffer.allocateDirect(length); buffer.order(ByteOrder.nativeOrder()); for (int i = startSeg; i <= endSeg; i++) { buffer.put(file.getChannel().map(FileChannel.MapMode.READ_ONLY, segPosition[i], segLength[i])); } buffer.rewind(); return buffer; } MappedByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, segPosition[startSeg], length); buffer.order(ByteOrder.nativeOrder()); return buffer; } public static RandomAccessFile getRandomAccessFile(FileImageInputStream fstream) { try { Field fRaf = FileImageInputStream.class.getDeclaredField("raf"); if (fRaf != null) { fRaf.setAccessible(true); return (RandomAccessFile) fRaf.get(fstream); } } catch (Exception e) { LOGGER.error("getFileDescriptor from FileImageInputStream", e); //$NON-NLS-1$ } return null; } public static RandomAccessFile getRandomAccessFile(FileImageOutputStream fstream) { try { Field fRaf = FileImageOutputStream.class.getDeclaredField("raf"); if (fRaf != null) { fRaf.setAccessible(true); return (RandomAccessFile) fRaf.get(fstream); } } catch (Exception e) { LOGGER.error("getFileDescriptor from FileImageOutputStream", e); //$NON-NLS-1$ } return null; } }