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.pIUnknown() 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
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 = pIUnknown() 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
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.pIUnknown() 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))