Search in sources :

Example 1 with ImageInfo

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());
            }
        }
    }
}
Also used : ImageInfo(net.pms.image.ImageInfo) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Example 2 with ImageInfo

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);
    }
}
Also used : ImageProcessingException(com.drew.imaging.ImageProcessingException) DCRaw(net.pms.encoders.DCRaw) PmsConfiguration(net.pms.configuration.PmsConfiguration) FileType(com.drew.imaging.FileType) BufferedInputStream(java.io.BufferedInputStream) Metadata(com.drew.metadata.Metadata) IOException(java.io.IOException) ParseException(net.pms.util.ParseException) ImageInfo(net.pms.image.ImageInfo) ImageFormat(net.pms.image.ImageFormat)

Example 3 with ImageInfo

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();
}
Also used : HypotheticalResult(net.pms.dlna.DLNAImageProfile.HypotheticalResult) ImageInfo(net.pms.image.ImageInfo)

Example 4 with ImageInfo

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());
        }
    }
}
Also used : ImageInfo(net.pms.image.ImageInfo) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Example 5 with ImageInfo

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);
}
Also used : ImagePlayer(net.pms.encoders.ImagePlayer) WebRender(net.pms.configuration.WebRender) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Headers(com.sun.net.httpserver.Headers) OutputStream(java.io.OutputStream) BufferedOutputStream(java.io.BufferedOutputStream) IOException(java.io.IOException) Range(net.pms.dlna.Range) Image(net.pms.image.Image) DLNAResource(net.pms.dlna.DLNAResource) ProcessWrapper(net.pms.io.ProcessWrapper) ByteArrayInputStream(java.io.ByteArrayInputStream) RootFolder(net.pms.dlna.RootFolder) ImageInfo(net.pms.image.ImageInfo) OutputParams(net.pms.io.OutputParams) BufferedOutputStream(java.io.BufferedOutputStream)

Aggregations

ImageInfo (net.pms.image.ImageInfo)5 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)2 IOException (java.io.IOException)2 FileType (com.drew.imaging.FileType)1 ImageProcessingException (com.drew.imaging.ImageProcessingException)1 Metadata (com.drew.metadata.Metadata)1 Headers (com.sun.net.httpserver.Headers)1 BufferedInputStream (java.io.BufferedInputStream)1 BufferedOutputStream (java.io.BufferedOutputStream)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 PmsConfiguration (net.pms.configuration.PmsConfiguration)1 WebRender (net.pms.configuration.WebRender)1 HypotheticalResult (net.pms.dlna.DLNAImageProfile.HypotheticalResult)1 DLNAResource (net.pms.dlna.DLNAResource)1 Range (net.pms.dlna.Range)1 RootFolder (net.pms.dlna.RootFolder)1 DCRaw (net.pms.encoders.DCRaw)1 ImagePlayer (net.pms.encoders.ImagePlayer)1