Beispiel #1
0
    def _load_bitmap_decoder(self, file, filename):
        data = file.read()

        # Create a HGLOBAL with image data
        hglob = kernel32.GlobalAlloc(GMEM_MOVEABLE, len(data))
        ptr = kernel32.GlobalLock(hglob)
        memmove(ptr, data, len(data))
        kernel32.GlobalUnlock(hglob)

        # Create IStream for the HGLOBAL
        stream = com.IUnknown()
        ole32.CreateStreamOnHGlobal(hglob, True, byref(stream))

        # Load image from stream
        decoder = IWICBitmapDecoder()
        status = self._factory.CreateDecoderFromStream(stream, None, WICDecodeMetadataCacheOnDemand, byref(decoder))
        if status != 0:
            stream.Release()
            raise ImageDecodeException('WIC cannot load %r' % (filename or file))

        return decoder, stream
Beispiel #2
0
    def _load_bitmap(self, file, filename):
        data = file.read()

        # Create a HGLOBAL with image data
        hglob = kernel32.GlobalAlloc(GMEM_MOVEABLE, len(data))
        ptr = kernel32.GlobalLock(hglob)
        memmove(ptr, data, len(data))
        kernel32.GlobalUnlock(hglob)

        # Create IStream for the HGLOBAL
        self.stream = IUnknown()
        ole32.CreateStreamOnHGlobal(hglob, True, byref(self.stream))

        # Load image from stream
        bitmap = c_void_p()
        status = gdiplus.GdipCreateBitmapFromStream(self.stream, byref(bitmap))
        if status != 0:
            self.stream.Release()
            raise ImageDecodeException('GDI+ cannot load %r' % (filename or file))

        return bitmap
Beispiel #3
0
    def __init__(self, filename, file=None):
        assert any([self.decode_audio, self.decode_video
                    ]), "Source must decode audio, video, or both, not none."
        self._current_audio_sample = None
        self._current_audio_buffer = None
        self._current_video_sample = None
        self._current_video_buffer = None
        self._timestamp = 0
        self._attributes = None
        self._stream_obj = None
        self._wfx = None
        self._stride = None

        self.set_config_attributes()

        # Create SourceReader
        self._source_reader = IMFSourceReader()

        # If it's a file, we need to load it as a stream.
        if file is not None:
            data = file.read()

            # Stole code from GDIPlus for older IStream support.
            hglob = kernel32.GlobalAlloc(GMEM_MOVEABLE, len(data))
            ptr = kernel32.GlobalLock(hglob)
            ctypes.memmove(ptr, data, len(data))
            kernel32.GlobalUnlock(hglob)

            # Create IStream
            self._stream_obj = com.IUnknown()
            ole32.CreateStreamOnHGlobal(hglob, True,
                                        ctypes.byref(self._stream_obj))

            imf_bytestream = IMFByteStream()

            # MFCreateMFByteStreamOnStreamEx for future async operations exists, however Windows 8+ only. Requires new interface
            # (Also unsure how/if new Windows async functions and callbacks work with ctypes.)
            MFCreateMFByteStreamOnStream(
                self._stream_obj,
                ctypes.byref(imf_bytestream))  # Allows 7 support still

            try:
                MFCreateSourceReaderFromByteStream(
                    imf_bytestream, self._attributes,
                    ctypes.byref(self._source_reader))
            except OSError as err:
                raise MediaDecodeException(err) from None
        else:
            # We can just load from filename if no file object specified..
            try:
                MFCreateSourceReaderFromURL(filename, self._attributes,
                                            ctypes.byref(self._source_reader))
            except OSError as err:
                raise MediaDecodeException(err) from None

        if self.decode_audio:
            self._load_audio()

        if self.decode_video:
            self._load_video()

        assert self.audio_format or self.video_format, "Source was decoded, but no video or audio streams were found."
Beispiel #4
0
    def __init__(self, filename, file=None):
        assert any([self.decode_audio, self.decode_video
                    ]), "Source must decode audio, video, or both, not none."
        self._current_audio_sample = None
        self._current_audio_buffer = None
        self._current_video_sample = None
        self._current_video_buffer = None
        self._timestamp = 0
        self._attributes = None
        self._stream_obj = None
        self._imf_bytestream = None
        self._wfx = None
        self._stride = None

        self.set_config_attributes()

        # Create SourceReader
        self._source_reader = IMFSourceReader()

        # If it's a file, we need to load it as a stream.
        if file is not None:
            data = file.read()

            self._imf_bytestream = IMFByteStream()

            data_len = len(data)

            if WINDOWS_7_OR_GREATER:
                # Stole code from GDIPlus for older IStream support.
                hglob = kernel32.GlobalAlloc(GMEM_MOVEABLE, data_len)
                ptr = kernel32.GlobalLock(hglob)
                ctypes.memmove(ptr, data, data_len)
                kernel32.GlobalUnlock(hglob)

                # Create IStream
                self._stream_obj = com.IUnknown()
                ole32.CreateStreamOnHGlobal(hglob, True,
                                            ctypes.byref(self._stream_obj))

                # MFCreateMFByteStreamOnStreamEx for future async operations exists, however Windows 8+ only. Requires new interface
                # (Also unsure how/if new Windows async functions and callbacks work with ctypes.)
                MFCreateMFByteStreamOnStream(
                    self._stream_obj, ctypes.byref(self._imf_bytestream))
            else:
                # Vista does not support MFCreateMFByteStreamOnStream.
                # HACK: Create file in Windows temp folder to write our byte data to.
                # (Will be automatically deleted when IMFByteStream is Released.)
                MFCreateTempFile(MF_ACCESSMODE_READWRITE,
                                 MF_OPENMODE_DELETE_IF_EXIST,
                                 MF_FILEFLAGS_NONE,
                                 ctypes.byref(self._imf_bytestream))

                wrote_length = ULONG()
                data_ptr = cast(data, POINTER(BYTE))
                self._imf_bytestream.Write(data_ptr, data_len,
                                           ctypes.byref(wrote_length))
                self._imf_bytestream.SetCurrentPosition(0)

                if wrote_length.value != data_len:
                    raise MediaDecodeException(
                        "Could not write all of the data to the bytestream file."
                    )

            try:
                MFCreateSourceReaderFromByteStream(
                    self._imf_bytestream, self._attributes,
                    ctypes.byref(self._source_reader))
            except OSError as err:
                raise MediaDecodeException(err) from None
        else:
            # We can just load from filename if no file object specified..
            try:
                MFCreateSourceReaderFromURL(filename, self._attributes,
                                            ctypes.byref(self._source_reader))
            except OSError as err:
                raise MediaDecodeException(err) from None

        if self.decode_audio:
            self._load_audio()

        if self.decode_video:
            self._load_video()

        assert self.audio_format or self.video_format, "Source was decoded, but no video or audio streams were found."

        # Get duration of the media file after everything has been ok to decode.
        try:
            prop = PROPVARIANT()
            self._source_reader.GetPresentationAttribute(
                MF_SOURCE_READER_MEDIASOURCE, ctypes.byref(MF_PD_DURATION),
                ctypes.byref(prop))

            self._duration = timestamp_from_wmf(prop.llVal)
            ole32.PropVariantClear(ctypes.byref(prop))
        except OSError:
            warnings.warn(
                "Could not determine duration of media file: '{}'.".format(
                    filename))