use of net.pms.image.ImageInfo in project UniversalMediaServer by UniversalMediaServer.
the class DLNAResource method appendThumbnail.
/**
* Generate and append the thumbnail {@code res} and
* {@code upnp:albumArtURI} entries for the thumbnail.
*
* @param sb the {@link StringBuilder} to append the response to.
* @param mediaType the {@link MediaType} of this {@link DLNAResource}.
* @param renderer the {@link Renderer} used for filtering or {@code null}
* for no filtering.
*/
@SuppressFBWarnings("SF_SWITCH_NO_DEFAULT")
private void appendThumbnail(StringBuilder sb, MediaType mediaType, Renderer renderer) {
// Images add thumbnail resources together with the image resources in appendImage()
if (MediaType.IMAGE != mediaType) {
ImageInfo imageInfo = thumbnailImageInfo != null ? thumbnailImageInfo : getMedia() != null && getMedia().getThumb() != null && getMedia().getThumb().getImageInfo() != null ? getMedia().getThumb().getImageInfo() : null;
// Only include GIF elements if the source is a GIF and it's supported by the renderer.
boolean includeGIF = imageInfo != null && imageInfo.getFormat() == ImageFormat.GIF && DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.GIF_LRG, renderer);
// Add elements in any order, it's sorted by priority later
List<DLNAImageResElement> resElements = new ArrayList<>();
// Always include JPEG_TN as per DLNA standard
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_TN, imageInfo, true));
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.JPEG_SM, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_SM, imageInfo, true));
}
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.PNG_TN, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.PNG_TN, imageInfo, true));
}
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.PNG_LRG, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.PNG_LRG, imageInfo, true));
}
if (imageInfo != null) {
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.JPEG_RES_H_V, renderer) && imageInfo.getWidth() > 0 && imageInfo.getHeight() > 0) {
// Offer the exact resolution as JPEG_RES_H_V
DLNAImageProfile exactResolution = DLNAImageProfile.createJPEG_RES_H_V(imageInfo.getWidth(), imageInfo.getHeight());
resElements.add(new DLNAImageResElement(exactResolution, imageInfo, true));
}
if (includeGIF) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.GIF_LRG, imageInfo, true));
}
if (!DLNAImageProfile.JPEG_SM.isResolutionCorrect(imageInfo)) {
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.JPEG_MED, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_MED, imageInfo, true));
}
if (!DLNAImageProfile.JPEG_MED.isResolutionCorrect(imageInfo)) {
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.JPEG_LRG, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_LRG, imageInfo, true));
}
}
}
}
// Sort the elements by priority
Collections.sort(resElements, DLNAImageResElement.getComparator(imageInfo != null ? imageInfo.getFormat() : ImageFormat.JPEG));
for (DLNAImageResElement resElement : resElements) {
addImageResource(sb, resElement);
}
for (DLNAImageResElement resElement : resElements) {
// Offering AlbumArt for video breaks the standard, but some renderers need it
switch(resElement.getProfile().toInt()) {
case DLNAImageProfile.GIF_LRG_INT:
case DLNAImageProfile.JPEG_SM_INT:
case DLNAImageProfile.JPEG_TN_INT:
case DLNAImageProfile.PNG_LRG_INT:
case DLNAImageProfile.PNG_TN_INT:
addAlbumArt(sb, resElement.getProfile());
}
}
}
}
use of net.pms.image.ImageInfo in project UniversalMediaServer by UniversalMediaServer.
the class RAW method parse.
@Override
public void parse(DLNAMediaInfo media, InputFile file, int type, RendererConfiguration renderer) {
boolean trace = LOGGER.isTraceEnabled();
if (media == null || file == null || file.getFile() == null) {
// Parsing is impossible
if (trace) {
if (file != null && file.getFile() != null) {
LOGGER.trace("Not parsing RAW file \"{}\" because media is null", file.getFile().getName());
} else {
LOGGER.error("Not parsing RAW file because file is null");
}
}
return;
}
PmsConfiguration configuration = PMS.getConfiguration(renderer);
try {
// Only parse using DCRaw if it is enabled
DCRaw dcraw = (DCRaw) PlayerFactory.getEnabledPlayer(DCRaw.class, this);
if (dcraw != null) {
if (trace) {
LOGGER.trace("Parsing RAW image \"{}\" with DCRaw", file.getFile().getName());
}
dcraw.parse(media, file.getFile());
media.setCodecV(FormatConfiguration.RAW);
media.setContainer(FormatConfiguration.RAW);
ImageInfo imageInfo = null;
Metadata metadata = null;
FileType fileType = null;
try (BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(file.getFile().toPath()))) {
fileType = FileTypeDetector.detectFileType(inputStream);
metadata = ImagesUtil.getMetadata(inputStream, fileType);
} catch (IOException e) {
metadata = new Metadata();
LOGGER.debug("Error reading \"{}\": {}", file.getFile().getAbsolutePath(), e.getMessage());
LOGGER.trace("", e);
} catch (ImageProcessingException e) {
metadata = new Metadata();
LOGGER.debug("Error parsing {} metadata for \"{}\": {}", fileType.toString().toUpperCase(Locale.ROOT), file.getFile().getAbsolutePath(), e.getMessage());
LOGGER.trace("", e);
}
if (fileType == FileType.Arw && !ImagesUtil.isARW(metadata)) {
fileType = FileType.Tiff;
}
ImageFormat format = ImageFormat.toImageFormat(fileType);
if (format == null || format == ImageFormat.TIFF) {
format = ImageFormat.toImageFormat(metadata);
if (format == null || format == ImageFormat.TIFF) {
format = ImageFormat.RAW;
}
}
try {
imageInfo = ImageInfo.create(media.getWidth(), media.getHeight(), metadata, format, file.getSize(), true, false);
if (trace) {
LOGGER.trace("Parsing of RAW image \"{}\" completed: {}", file.getFile().getName(), imageInfo);
}
} catch (ParseException e) {
LOGGER.warn("Unable to parse \"{}\": {}", file.getFile().getAbsolutePath(), e.getMessage());
LOGGER.trace("", e);
}
media.setImageInfo(imageInfo);
if (media.getWidth() > 0 && media.getHeight() > 0 && configuration.getImageThumbnailsEnabled()) {
byte[] image = new DCRaw().getThumbnail(null, file.getFile().getAbsolutePath(), imageInfo);
media.setThumb(DLNAThumbnail.toThumbnail(image, 320, 320, ScaleType.MAX, ImageFormat.JPEG, false));
}
} else {
if (trace) {
LOGGER.trace("Parsing RAW image \"{}\" as a regular image because DCRaw is disabled", file.getFile().getName());
}
ImagesUtil.parseImage(file.getFile(), media);
}
media.setSize(file.getSize());
media.setImageCount(1);
media.postParse(type, file);
media.setMediaparsed(true);
} catch (IOException e) {
LOGGER.error("Error parsing RAW file \"{}\": {}", file.getFile().getAbsolutePath(), e.getMessage());
LOGGER.trace("", e);
}
}
use of net.pms.image.ImageInfo in project UniversalMediaServer by UniversalMediaServer.
the class DLNAResource method getDlnaContentFeatures.
public String getDlnaContentFeatures(DLNAImageProfile profile, boolean thumbnailRequest) {
StringBuilder sb = new StringBuilder();
if (profile != null) {
sb.append("DLNA.ORG_PN=").append(profile);
}
ImageInfo thumbnailImageInfo = this.thumbnailImageInfo != null ? this.thumbnailImageInfo : getMedia() != null && getMedia().getThumb() != null ? getMedia().getThumb().getImageInfo() : null;
ImageInfo imageInfo = thumbnailRequest ? thumbnailImageInfo : media != null ? media.getImageInfo() : null;
if (profile != null && !thumbnailRequest && thumbnailImageInfo != null && profile.useThumbnailSource(imageInfo, thumbnailImageInfo)) {
imageInfo = thumbnailImageInfo;
}
if (profile != null && imageInfo != null) {
HypotheticalResult hypotheticalResult = profile.calculateHypotheticalProperties(imageInfo);
if (sb.length() > 0) {
sb.append(';');
}
sb.append("DLNA.ORG_CI=").append(hypotheticalResult.conversionNeeded ? "1" : "0");
}
if (sb.length() > 0) {
sb.append(';');
}
sb.append("DLNA.ORG_FLAGS=00900000000000000000000000000000");
return sb.toString();
}
use of net.pms.image.ImageInfo in project UniversalMediaServer by UniversalMediaServer.
the class DLNAResource method appendImage.
/**
* Generate and append image and thumbnail {@code res} and
* {@code upnp:albumArtURI} entries for the image.
*
* @param sb The {@link StringBuilder} to append the elements to.
* @param renderer the {@link Renderer} used for filtering or {@code null}
* for no filtering.
*/
@SuppressFBWarnings("SF_SWITCH_NO_DEFAULT")
private void appendImage(StringBuilder sb, Renderer renderer) {
/*
* There's no technical difference between the image itself and the
* thumbnail for an object.item.imageItem, they are all simply listed
* as <res> entries. To UMS there is a difference since the thumbnail
* is cached while the image itself is not. The idea here is therefore
* to offer any size smaller than or equal to the cached thumbnail
* using the cached thumbnail as the source, and offer anything bigger
* using the image itself as the source.
*
* If the thumbnail isn't parsed
* yet, we don't know the size of the thumbnail. In those situations
* we simply use the thumbnail for the _TN entries and the image for
* all others.
*/
ImageInfo imageInfo = media.getImageInfo();
ImageInfo thumbnailImageInfo = this.thumbnailImageInfo != null ? this.thumbnailImageInfo : getMedia() != null && getMedia().getThumb() != null ? getMedia().getThumb().getImageInfo() : null;
// Only include GIF elements if the source is a GIF and it's supported by the renderer.
boolean includeGIF = imageInfo != null && imageInfo.getFormat() == ImageFormat.GIF && DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.GIF_LRG, renderer);
// Add elements in any order, it's sorted by priority later
List<DLNAImageResElement> resElements = new ArrayList<>();
// Always offer JPEG_TN as per DLNA standard
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_TN, thumbnailImageInfo != null ? thumbnailImageInfo : imageInfo, true));
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.PNG_TN, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.PNG_TN, thumbnailImageInfo != null ? thumbnailImageInfo : imageInfo, true));
}
if (imageInfo != null) {
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.JPEG_RES_H_V, renderer) && imageInfo.getWidth() > 0 && imageInfo.getHeight() > 0) {
// Offer the exact resolution as JPEG_RES_H_V
DLNAImageProfile exactResolution = DLNAImageProfile.createJPEG_RES_H_V(imageInfo.getWidth(), imageInfo.getHeight());
resElements.add(new DLNAImageResElement(exactResolution, imageInfo, exactResolution.useThumbnailSource(imageInfo, thumbnailImageInfo)));
}
// Always offer JPEG_SM for images as per DLNA standard
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_SM, imageInfo, DLNAImageProfile.JPEG_SM.useThumbnailSource(imageInfo, thumbnailImageInfo)));
if (!DLNAImageProfile.PNG_TN.isResolutionCorrect(imageInfo)) {
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.PNG_LRG, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.PNG_LRG, imageInfo, DLNAImageProfile.PNG_LRG.useThumbnailSource(imageInfo, thumbnailImageInfo)));
}
if (includeGIF) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.GIF_LRG, imageInfo, DLNAImageProfile.GIF_LRG.useThumbnailSource(imageInfo, thumbnailImageInfo)));
}
if (!DLNAImageProfile.JPEG_SM.isResolutionCorrect(imageInfo)) {
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.JPEG_MED, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_MED, imageInfo, DLNAImageProfile.JPEG_MED.useThumbnailSource(imageInfo, thumbnailImageInfo)));
}
if (!DLNAImageProfile.JPEG_MED.isResolutionCorrect(imageInfo)) {
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.PNG_LRG, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_LRG, imageInfo, DLNAImageProfile.JPEG_LRG.useThumbnailSource(imageInfo, thumbnailImageInfo)));
}
}
}
}
} else {
// This shouldn't normally be the case, parsing must have failed or
// isn't finished yet so we just make a generic offer.
// Always offer JPEG_SM for images as per DLNA standard
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_SM, null, false));
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.JPEG_LRG, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.JPEG_LRG, null, false));
}
if (DLNAImageResElement.isImageProfileSupported(DLNAImageProfile.PNG_LRG, renderer)) {
resElements.add(new DLNAImageResElement(DLNAImageProfile.PNG_LRG, null, false));
}
LOGGER.debug("Warning: Image \"{}\" isn't parsed when DIDL-Lite is generated", this.getName());
}
// Sort the elements by priority
Collections.sort(resElements, DLNAImageResElement.getComparator(imageInfo != null ? imageInfo.getFormat() : ImageFormat.JPEG));
for (DLNAImageResElement resElement : resElements) {
addImageResource(sb, resElement);
}
for (DLNAImageResElement resElement : resElements) {
// Offering AlbumArt here breaks the standard, but some renderers need it
switch(resElement.getProfile().toInt()) {
case DLNAImageProfile.GIF_LRG_INT:
case DLNAImageProfile.JPEG_SM_INT:
case DLNAImageProfile.JPEG_TN_INT:
case DLNAImageProfile.PNG_LRG_INT:
case DLNAImageProfile.PNG_TN_INT:
addAlbumArt(sb, resElement.getProfile());
}
}
}
use of net.pms.image.ImageInfo in project UniversalMediaServer by UniversalMediaServer.
the class RemoteRawHandler method handle.
@Override
public void handle(HttpExchange t) throws IOException {
LOGGER.debug("got a raw request " + t.getRequestURI());
if (RemoteUtil.deny(t)) {
throw new IOException("Access denied");
}
RootFolder root = parent.getRoot(RemoteUtil.userName(t), t);
if (root == null) {
throw new IOException("Unknown root");
}
String id;
id = RemoteUtil.strip(RemoteUtil.getId("raw/", t));
LOGGER.debug("raw id " + id);
List<DLNAResource> res = root.getDLNAResources(id, false, 0, 0, root.getDefaultRenderer());
if (res.size() != 1) {
// another error
LOGGER.debug("media unkonwn");
throw new IOException("Bad id");
}
DLNAResource dlna = res.get(0);
long len;
String mime = null;
InputStream in;
Range.Byte range;
if (dlna.getMedia() != null && dlna.getMedia().isImage() && dlna.getMedia().getImageInfo() != null) {
boolean supported = false;
ImageInfo imageInfo = dlna.getMedia().getImageInfo();
if (root.getDefaultRenderer() instanceof WebRender) {
WebRender renderer = (WebRender) root.getDefaultRenderer();
supported = renderer.isImageFormatSupported(imageInfo.getFormat());
}
mime = dlna.getFormat() != null ? dlna.getFormat().mimeType() : root.getDefaultRenderer().getMimeType(dlna.mimeType(), dlna.getMedia());
len = supported && imageInfo.getSize() != ImageInfo.SIZE_UNKNOWN ? imageInfo.getSize() : dlna.length();
range = new Range.Byte(0l, len);
if (supported) {
in = dlna.getInputStream();
} else {
InputStream imageInputStream;
if (dlna.getPlayer() instanceof ImagePlayer) {
ProcessWrapper transcodeProcess = dlna.getPlayer().launchTranscode(dlna, dlna.getMedia(), new OutputParams(PMS.getConfiguration()));
imageInputStream = transcodeProcess != null ? transcodeProcess.getInputStream(0) : null;
} else {
imageInputStream = dlna.getInputStream();
}
Image image = Image.toImage(imageInputStream, 3840, 2400, ScaleType.MAX, ImageFormat.JPEG, false);
len = image.getBytes(false).length;
in = image == null ? null : new ByteArrayInputStream(image.getBytes(false));
}
} else {
len = dlna.length();
dlna.setPlayer(null);
range = RemoteUtil.parseRange(t.getRequestHeaders(), len);
in = dlna.getInputStream(range, root.getDefaultRenderer());
if (len == 0) {
// For web resources actual length may be unknown until we open the stream
len = dlna.length();
}
mime = root.getDefaultRenderer().getMimeType(dlna.mimeType(), dlna.getMedia());
}
Headers hdr = t.getResponseHeaders();
LOGGER.debug("Sending media \"{}\" with mime type \"{}\"", dlna, mime);
hdr.add("Content-Type", mime);
hdr.add("Accept-Ranges", "bytes");
hdr.add("Server", PMS.get().getServerName());
hdr.add("Connection", "keep-alive");
hdr.add("Transfer-Encoding", "chunked");
if (in.available() != len) {
hdr.add("Content-Range", "bytes " + range.getStart() + "-" + in.available() + "/" + len);
t.sendResponseHeaders(206, in.available());
} else {
t.sendResponseHeaders(200, 0);
}
OutputStream os = new BufferedOutputStream(t.getResponseBody(), 512 * 1024);
LOGGER.debug("start raw dump");
RemoteUtil.dump(in, os);
}
Aggregations