def decode_animation(self, file, filename):
        # TODO: Stop playing chicken with the GC
        # TODO: Cleanup in errors

        quicktime.EnterMovies()

        data_ref = self._get_data_ref(file, filename)
        if not data_ref:
            raise ImageDecodeException(filename or file)

        movie = c_void_p()
        id = c_short()
        result = quicktime.NewMovieFromDataRef(byref(movie), newMovieActive, 0,
                                               data_ref,
                                               PointerDataHandlerSubType)

        if not movie:
            #_oscheck(result)
            raise ImageDecodeException(filename or file)
        quicktime.GoToBeginningOfMovie(movie)

        time_scale = float(quicktime.GetMovieTimeScale(movie))

        format, qtformat = self._get_formats()

        # Get movie width and height
        rect = Rect()
        quicktime.GetMovieBox(movie, byref(rect))
        width = rect.right
        height = rect.bottom
        pitch = len(format) * width

        # Set gworld
        buffer = (c_byte * (width * height * len(format)))()
        world = GWorldPtr()
        quicktime.QTNewGWorldFromPtr(byref(world), qtformat, byref(rect),
                                     c_void_p(), c_void_p(), 0, buffer,
                                     len(format) * width)
        quicktime.SetGWorld(world, 0)
        quicktime.SetMovieGWorld(movie, world, 0)

        visual = quicktime.GetMovieIndTrackType(movie, 1,
                                                VisualMediaCharacteristic,
                                                movieTrackCharacteristic)
        if not visual:
            raise ImageDecodeException('No video track')

        time = 0

        interesting_time = c_int()
        quicktime.GetTrackNextInterestingTime(visual,
                                              nextTimeMediaSample, time, 1,
                                              byref(interesting_time), None)
        duration = interesting_time.value / time_scale

        frames = []

        while time >= 0:
            result = quicktime.GetMoviesError()
            if result == noErr:
                # force redraw
                result = quicktime.UpdateMovie(movie)
            if result == noErr:
                # process movie
                quicktime.MoviesTask(movie, 0)
                result = quicktime.GetMoviesError()
            _oscheck(result)

            buffer_copy = (c_byte * len(buffer))()
            memmove(buffer_copy, buffer, len(buffer))
            image = ImageData(width, height, format, buffer_copy, -pitch)
            frames.append(AnimationFrame(image, duration))

            interesting_time = c_int()
            duration = c_int()
            quicktime.GetTrackNextInterestingTime(visual, nextTimeMediaSample,
                                                  time, 1,
                                                  byref(interesting_time),
                                                  byref(duration))

            quicktime.SetMovieTimeValue(movie, interesting_time)
            time = interesting_time.value
            duration = duration.value / time_scale
            if duration <= 0.01:
                duration = 0.1

        quicktime.DisposeMovie(movie)
        carbon.DisposeHandle(data_ref)

        quicktime.ExitMovies()

        return Animation(frames)
Exemple #2
0
_oscheck(result)

sound = ctypes.c_void_p()
fileid = ctypes.c_short(0)
quicktime.NewMovieFromDataRef.argtypes = (ctypes.POINTER(ctypes.c_void_p),
                                          ctypes.c_short,
                                          ctypes.POINTER(ctypes.c_short),
                                          ctypes.c_void_p, ctypes.c_ulong)

newMovieActive = 1

result = quicktime.NewMovieFromDataRef(ctypes.byref(sound), newMovieActive,
                                       ctypes.byref(fileid), data_ref,
                                       data_ref_type)
_oscheck(result)

carbon.CFRelease(filename)

quicktime.StartMovie(sound)

try:
    while not quicktime.IsMovieDone(sound):
        quicktime.MoviesTask(0)
        time.sleep(0.1)
except KeyboardInterrupt:
    pass

quicktime.StopMovie(sound)

quicktime.ExitMovies()