From 15318cad33835e4e2dc620d033e43cd930676cdd Mon Sep 17 00:00:00 2001 From: kergoth Date: Fri, 25 Jan 2002 22:14:26 +0000 Subject: Initial revision --- (limited to 'core/multimedia/opieplayer') diff --git a/core/multimedia/opieplayer/.cvsignore b/core/multimedia/opieplayer/.cvsignore new file mode 100644 index 0000000..6fe2396 --- a/dev/null +++ b/core/multimedia/opieplayer/.cvsignore @@ -0,0 +1,2 @@ +moc_* +Makefile diff --git a/core/multimedia/opieplayer/Makefile.in b/core/multimedia/opieplayer/Makefile.in new file mode 100644 index 0000000..5fca66e --- a/dev/null +++ b/core/multimedia/opieplayer/Makefile.in @@ -0,0 +1,280 @@ +############################################################################# + +####### Compiler, tools and options + +CXX = $(SYSCONF_CXX) $(QT_CXX_MT) +CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) -DQCONFIG=\"qpe\" +CC = $(SYSCONF_CC) $(QT_C_MT) +CFLAGS = $(SYSCONF_CFLAGS) -DQCONFIG=\"qpe\" +INCPATH = -I$(QPEDIR)/include +LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) +LIBS = $(SUBLIBS) -lqpe -lpthread $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP) +MOC = $(SYSCONF_MOC) +UIC = $(SYSCONF_UIC) + +####### Target + +DESTDIR = $(QPEDIR)/bin/ +VER_MAJ = 1 +VER_MIN = 0 +VER_PATCH = 0 +TARGET = mpegplayer +TARGET1 = lib$(TARGET).so.$(VER_MAJ) + +####### Files + +HEADERS = loopcontrol.h \ + mediaplayerplugininterface.h \ + playlistselection.h \ + mediaplayerstate.h \ + videowidget.h \ + audiowidget.h \ + playlistwidget.h \ + mediaplayer.h \ + audiodevice.h +SOURCES = main.cpp \ + loopcontrol.cpp \ + playlistselection.cpp \ + mediaplayerstate.cpp \ + videowidget.cpp \ + audiowidget.cpp \ + playlistwidget.cpp \ + mediaplayer.cpp \ + audiodevice.cpp +OBJECTS = main.o \ + loopcontrol.o \ + playlistselection.o \ + mediaplayerstate.o \ + videowidget.o \ + audiowidget.o \ + playlistwidget.o \ + mediaplayer.o \ + audiodevice.o +INTERFACES = +UICDECLS = +UICIMPLS = +SRCMOC = moc_loopcontrol.cpp \ + moc_playlistselection.cpp \ + moc_mediaplayerstate.cpp \ + moc_videowidget.cpp \ + moc_audiowidget.cpp \ + moc_playlistwidget.cpp \ + moc_mediaplayer.cpp \ + moc_audiodevice.cpp +OBJMOC = moc_loopcontrol.o \ + moc_playlistselection.o \ + moc_mediaplayerstate.o \ + moc_videowidget.o \ + moc_audiowidget.o \ + moc_playlistwidget.o \ + moc_mediaplayer.o \ + moc_audiodevice.o + + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + + +all: $(DESTDIR)$(TARGET) + +$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) + $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) + +moc: $(SRCMOC) + +tmake: + tmake mpegplayer.pro + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) + -rm -f *~ core + -rm -f allmoc.cpp + +####### Extension Modules + +listpromodules: + @echo + +listallmodules: + @echo + +listaddonpromodules: + @echo + +listaddonentmodules: + @echo + + +REQUIRES= + +####### Sub-libraries + + +###### Combined headers + + + +####### Compile + +main.o: main.cpp \ + $(QPEDIR)/include/qpe/qpeapplication.h \ + mediaplayerstate.h \ + playlistwidget.h \ + $(QPEDIR)/include/qpe/applnk.h \ + audiowidget.h \ + videowidget.h \ + loopcontrol.h \ + mediaplayer.h \ + $(QPEDIR)/include/qpe/qlibrary.h \ + $(QPEDIR)/include/qpe/qcom.h \ + $(QPEDIR)/include/qpe/quuid.h \ + mediaplayerplugininterface.h + +loopcontrol.o: loopcontrol.cpp \ + $(QPEDIR)/include/qpe/qpeapplication.h \ + $(QPEDIR)/include/qpe/qcopenvelope_qws.h \ + loopcontrol.h \ + videowidget.h \ + audiodevice.h \ + mediaplayerplugininterface.h \ + $(QPEDIR)/include/qpe/qcom.h \ + $(QPEDIR)/include/qpe/quuid.h \ + mediaplayerstate.h + +playlistselection.o: playlistselection.cpp \ + $(QPEDIR)/include/qpe/applnk.h \ + $(QPEDIR)/include/qpe/resource.h \ + playlistselection.h + +mediaplayerstate.o: mediaplayerstate.cpp \ + $(QPEDIR)/include/qpe/qpeapplication.h \ + $(QPEDIR)/include/qpe/qlibrary.h \ + $(QPEDIR)/include/qpe/qcom.h \ + $(QPEDIR)/include/qpe/quuid.h \ + $(QPEDIR)/include/qpe/config.h \ + mediaplayerplugininterface.h \ + mediaplayerstate.h \ + libmad/libmadpluginimpl.h \ + libmpeg3/libmpeg3pluginimpl.h \ + wavplugin/wavpluginimpl.h + +videowidget.o: videowidget.cpp \ + $(QPEDIR)/include/qpe/resource.h \ + videowidget.h \ + mediaplayerplugininterface.h \ + $(QPEDIR)/include/qpe/qcom.h \ + $(QPEDIR)/include/qpe/quuid.h \ + mediaplayerstate.h + +audiowidget.o: audiowidget.cpp \ + $(QPEDIR)/include/qpe/resource.h \ + audiowidget.h \ + mediaplayerstate.h + +playlistwidget.o: playlistwidget.cpp \ + $(QPEDIR)/include/qpe/qpemenubar.h \ + $(QPEDIR)/include/qpe/qpetoolbar.h \ + $(QPEDIR)/include/qpe/fileselector.h \ + $(QPEDIR)/include/qpe/applnk.h \ + $(QPEDIR)/include/qpe/config.h \ + $(QPEDIR)/include/qpe/global.h \ + $(QPEDIR)/include/qpe/resource.h \ + playlistselection.h \ + playlistwidget.h \ + mediaplayerstate.h + +mediaplayer.o: mediaplayer.cpp \ + $(QPEDIR)/include/qpe/qpeapplication.h \ + $(QPEDIR)/include/qpe/qlibrary.h \ + $(QPEDIR)/include/qpe/qcom.h \ + $(QPEDIR)/include/qpe/quuid.h \ + $(QPEDIR)/include/qpe/resource.h \ + $(QPEDIR)/include/qpe/config.h \ + mediaplayer.h \ + mediaplayerplugininterface.h \ + playlistwidget.h \ + $(QPEDIR)/include/qpe/applnk.h \ + audiowidget.h \ + loopcontrol.h \ + audiodevice.h \ + mediaplayerstate.h + +audiodevice.o: audiodevice.cpp \ + $(QPEDIR)/include/qpe/qpeapplication.h \ + $(QPEDIR)/include/qpe/config.h \ + audiodevice.h \ + $(QPEDIR)/include/qpe/qcopenvelope_qws.h + +moc_loopcontrol.o: moc_loopcontrol.cpp \ + loopcontrol.h + +moc_playlistselection.o: moc_playlistselection.cpp \ + playlistselection.h \ + $(QPEDIR)/include/qpe/applnk.h + +moc_mediaplayerstate.o: moc_mediaplayerstate.cpp \ + mediaplayerstate.h + +moc_videowidget.o: moc_videowidget.cpp \ + videowidget.h + +moc_audiowidget.o: moc_audiowidget.cpp \ + audiowidget.h + +moc_playlistwidget.o: moc_playlistwidget.cpp \ + playlistwidget.h \ + $(QPEDIR)/include/qpe/applnk.h + +moc_mediaplayer.o: moc_mediaplayer.cpp \ + mediaplayer.h \ + $(QPEDIR)/include/qpe/qlibrary.h \ + $(QPEDIR)/include/qpe/qcom.h \ + $(QPEDIR)/include/qpe/quuid.h \ + mediaplayerplugininterface.h + +moc_audiodevice.o: moc_audiodevice.cpp \ + audiodevice.h + +moc_loopcontrol.cpp: loopcontrol.h + $(MOC) loopcontrol.h -o moc_loopcontrol.cpp + +moc_playlistselection.cpp: playlistselection.h + $(MOC) playlistselection.h -o moc_playlistselection.cpp + +moc_mediaplayerstate.cpp: mediaplayerstate.h + $(MOC) mediaplayerstate.h -o moc_mediaplayerstate.cpp + +moc_videowidget.cpp: videowidget.h + $(MOC) videowidget.h -o moc_videowidget.cpp + +moc_audiowidget.cpp: audiowidget.h + $(MOC) audiowidget.h -o moc_audiowidget.cpp + +moc_playlistwidget.cpp: playlistwidget.h + $(MOC) playlistwidget.h -o moc_playlistwidget.cpp + +moc_mediaplayer.cpp: mediaplayer.h + $(MOC) mediaplayer.h -o moc_mediaplayer.cpp + +moc_audiodevice.cpp: audiodevice.h + $(MOC) audiodevice.h -o moc_audiodevice.cpp + + diff --git a/core/multimedia/opieplayer/audiodevice.cpp b/core/multimedia/opieplayer/audiodevice.cpp new file mode 100644 index 0000000..8861015 --- a/dev/null +++ b/core/multimedia/opieplayer/audiodevice.cpp @@ -0,0 +1,386 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include "audiodevice.h" + +#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP) +#include "qpe/qcopenvelope_qws.h" +#endif + +#ifdef Q_WS_WIN +#include +#include +#include +#endif + +#if defined(Q_WS_X11) || defined(Q_WS_QWS) +#include +#include +#include +#include +#include +#include +#include +#endif + +#if defined(Q_OS_WIN32) +static const int expectedBytesPerMilliSecond = 2 * 2 * 44000 / 1000; +static const int timerResolutionMilliSeconds = 30; +static const int sound_fragment_bytes = timerResolutionMilliSeconds * expectedBytesPerMilliSecond; +#else +# if defined(QT_QWS_IPAQ) +static const int sound_fragment_shift = 14; +# else +static const int sound_fragment_shift = 16; +# endif +static const int sound_fragment_bytes = (1<> 16; +#else + int mixerHandle = open( "/dev/mixer", O_RDWR ); + if ( mixerHandle >= 0 ) { + ioctl( mixerHandle, MIXER_READ(0), &volume ); + close( mixerHandle ); + } else + qDebug( "get volume of audio device failed" ); + leftVolume = ((volume & 0x00FF) << 16) / 101; + rightVolume = ((volume & 0xFF00) << 8) / 101; +#endif +} + + +void AudioDevice::setVolume( unsigned int leftVolume, unsigned int rightVolume, bool muted ) { + AudioDevicePrivate::muted = muted; + if ( muted ) { + AudioDevicePrivate::leftVolume = leftVolume; + AudioDevicePrivate::rightVolume = rightVolume; + leftVolume = 0; + rightVolume = 0; + } else { + leftVolume = ( (int) leftVolume < 0 ) ? 0 : (( leftVolume > 0xFFFF ) ? 0xFFFF : leftVolume ); + rightVolume = ( (int)rightVolume < 0 ) ? 0 : (( rightVolume > 0xFFFF ) ? 0xFFFF : rightVolume ); + } +#ifdef Q_OS_WIN32 + HWAVEOUT handle; + WAVEFORMATEX formatData; + formatData.cbSize = sizeof(WAVEFORMATEX); + formatData.wFormatTag = WAVE_FORMAT_PCM; + formatData.nAvgBytesPerSec = 4 * 44000; + formatData.nBlockAlign = 4; + formatData.nChannels = 2; + formatData.nSamplesPerSec = 44000; + formatData.wBitsPerSample = 16; + waveOutOpen(&handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL); + unsigned int volume = (rightVolume << 16) | leftVolume; + if ( waveOutSetVolume( handle, volume ) ) + qDebug( "set volume of audio device failed" ); + waveOutClose( handle ); +#else + // Volume can be from 0 to 100 which is 101 distinct values + unsigned int rV = (rightVolume * 101) >> 16; + +# if 0 + unsigned int lV = (leftVolume * 101) >> 16; + unsigned int volume = ((rV << 8) & 0xFF00) | (lV & 0x00FF); + int mixerHandle = 0; + if ( ( mixerHandle = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { + ioctl( mixerHandle, MIXER_WRITE(0), &volume ); + close( mixerHandle ); + } else + qDebug( "set volume of audio device failed" ); +# else + // This is the way this has to be done now I guess, doesn't allow for + // independant right and left channel setting, or setting for different outputs + Config cfg("Sound"); + cfg.setGroup("System"); + cfg.writeEntry("Volume",(int)rV); +# endif + +#endif +// qDebug( "setting volume to: 0x%x", volume ); +#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP) + // Send notification that the volume has changed + QCopEnvelope( "QPE/System", "volumeChange(bool)" ) << muted; +#endif +} + + + + +AudioDevice::AudioDevice( unsigned int f, unsigned int chs, unsigned int bps ) { + d = new AudioDevicePrivate; + d->frequency = f; + d->channels = chs; + d->bytesPerSample = bps; + + connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( volumeChanged(bool) ) ); + +#ifdef Q_OS_WIN32 + UINT result; + WAVEFORMATEX formatData; + formatData.cbSize = sizeof(WAVEFORMATEX); +/* + // Other possible formats windows supports + formatData.wFormatTag = WAVE_FORMAT_MPEG; + formatData.wFormatTag = WAVE_FORMAT_MPEGLAYER3; + formatData.wFormatTag = WAVE_FORMAT_ADPCM; +*/ + formatData.wFormatTag = WAVE_FORMAT_PCM; + formatData.nAvgBytesPerSec = bps * chs * f; + formatData.nBlockAlign = bps * chs; + formatData.nChannels = chs; + formatData.nSamplesPerSec = f; + formatData.wBitsPerSample = bps * 8; + // Open a waveform device for output + if (result = waveOutOpen((LPHWAVEOUT)&d->handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL)) { + QString errorMsg = "error opening audio device.\nReason: %i - "; + switch (result) { + case MMSYSERR_ALLOCATED: errorMsg += "Specified resource is already allocated."; break; + case MMSYSERR_BADDEVICEID: errorMsg += "Specified device identifier is out of range."; break; + case MMSYSERR_NODRIVER: errorMsg += "No device driver is present."; break; + case MMSYSERR_NOMEM: errorMsg += "Unable to allocate or lock memory."; break; + case WAVERR_BADFORMAT: errorMsg += "Attempted to open with an unsupported waveform-audio format."; break; + case WAVERR_SYNC: errorMsg += "The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag."; break; + default: errorMsg += "Undefined error"; break; + } + qDebug( errorMsg, result ); + } + + d->bufferSize = sound_fragment_bytes; +#else + + int fragments = 0x10000 * 8 + sound_fragment_shift; + int format = AFMT_S16_LE; + int capabilities = 0; + +#ifdef KEEP_DEVICE_OPEN + if ( AudioDevicePrivate::dspFd == 0 ) { +#endif + if ( ( d->handle = ::open( "/dev/dsp", O_WRONLY ) ) < 0 ) { + qDebug( "error opening audio device /dev/dsp, sending data to /dev/null instead" ); + d->handle = ::open( "/dev/null", O_WRONLY ); + } +#ifdef KEEP_DEVICE_OPEN + AudioDevicePrivate::dspFd = d->handle; + } else { + d->handle = AudioDevicePrivate::dspFd; + } +#endif + + ioctl( d->handle, SNDCTL_DSP_GETCAPS, &capabilities ); + ioctl( d->handle, SNDCTL_DSP_SETFRAGMENT, &fragments ); + ioctl( d->handle, SNDCTL_DSP_SETFMT, &format ); + ioctl( d->handle, SNDCTL_DSP_SPEED, &d->frequency ); + if ( ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels ) == -1 ) { + d->channels = ( d->channels == 1 ) ? 2 : d->channels; + ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels ); + } + + d->bufferSize = sound_fragment_bytes; + d->unwrittenBuffer = new char[d->bufferSize]; + d->unwritten = 0; + d->can_GETOSPACE = TRUE; // until we find otherwise + + //if ( chs != d->channels ) qDebug( "Wanted %d, got %d channels", chs, d->channels ); + //if ( f != d->frequency ) qDebug( "wanted %dHz, got %dHz", f, d->frequency ); + //if ( capabilities & DSP_CAP_BATCH ) qDebug( "Sound card has local buffer" ); + //if ( capabilities & DSP_CAP_REALTIME )qDebug( "Sound card has realtime sync" ); + //if ( capabilities & DSP_CAP_TRIGGER ) qDebug( "Sound card has precise trigger" ); + //if ( capabilities & DSP_CAP_MMAP ) qDebug( "Sound card can mmap" ); +#endif +} + + +AudioDevice::~AudioDevice() { +#ifdef Q_OS_WIN32 + waveOutClose( (HWAVEOUT)d->handle ); +#else +# ifndef KEEP_DEVICE_OPEN + close( d->handle ); // Now it should be safe to shut the handle +# endif + delete d->unwrittenBuffer; + delete d; +#endif +} + + +void AudioDevice::volumeChanged( bool muted ) +{ + AudioDevicePrivate::muted = muted; +} + + +void AudioDevice::write( char *buffer, unsigned int length ) +{ +#ifdef Q_OS_WIN32 + // returns immediately and (to be implemented) emits completedIO() when finished writing + WAVEHDR *lpWaveHdr = (WAVEHDR *)malloc( sizeof(WAVEHDR) ); + // maybe the buffer should be copied so that this fool proof, but its a performance hit + lpWaveHdr->lpData = buffer; + lpWaveHdr->dwBufferLength = length; + lpWaveHdr->dwFlags = 0L; + lpWaveHdr->dwLoops = 0L; + waveOutPrepareHeader( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) ); + // waveOutWrite returns immediately. the data is sent in the background. + if ( waveOutWrite( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) ) ) + qDebug( "failed to write block to audio device" ); + // emit completedIO(); +#else + int t = ::write( d->handle, buffer, length ); + if ( t<0 ) t = 0; + if ( t != (int)length) { + qDebug("Ahhh!! memcpys 1"); + memcpy(d->unwrittenBuffer,buffer+t,length-t); + d->unwritten = length-t; + } +#endif +} + + +unsigned int AudioDevice::channels() const +{ + return d->channels; +} + + +unsigned int AudioDevice::frequency() const +{ + return d->frequency; +} + + +unsigned int AudioDevice::bytesPerSample() const +{ + return d->bytesPerSample; +} + + +unsigned int AudioDevice::bufferSize() const +{ + return d->bufferSize; +} + +unsigned int AudioDevice::canWrite() const +{ +#ifdef Q_OS_WIN32 + return bufferSize(); // Any better? +#else + audio_buf_info info; + if ( d->can_GETOSPACE && ioctl(d->handle,SNDCTL_DSP_GETOSPACE,&info) ) { + d->can_GETOSPACE = FALSE; + fcntl( d->handle, F_SETFL, O_NONBLOCK ); + } + if ( d->can_GETOSPACE ) { + int t = info.fragments * sound_fragment_bytes; + return QMIN(t,(int)bufferSize()); + } else { + if ( d->unwritten ) { + int t = ::write( d->handle, d->unwrittenBuffer, d->unwritten ); + if ( t<0 ) t = 0; + if ( (unsigned)t!=d->unwritten ) { + memcpy(d->unwrittenBuffer,d->unwrittenBuffer+t,d->unwritten-t); + d->unwritten -= t; + } else { + d->unwritten = 0; + } + } + if ( d->unwritten ) + return 0; + else + return d->bufferSize; + } +#endif +} + + +int AudioDevice::bytesWritten() { +#ifdef Q_OS_WIN32 + MMTIME pmmt = { TIME_BYTES, 0 }; + if ( ( waveOutGetPosition( (HWAVEOUT)d->handle, &pmmt, sizeof(MMTIME) ) != MMSYSERR_NOERROR ) || ( pmmt.wType != TIME_BYTES ) ) { + qDebug( "failed to get audio device position" ); + return -1; + } + return pmmt.u.cb; +#else + int buffered = 0; + if ( ioctl( d->handle, SNDCTL_DSP_GETODELAY, &buffered ) ) { + qDebug( "failed to get audio device position" ); + return -1; + } + return buffered; +#endif +} + diff --git a/core/multimedia/opieplayer/audiodevice.h b/core/multimedia/opieplayer/audiodevice.h new file mode 100644 index 0000000..928f134 --- a/dev/null +++ b/core/multimedia/opieplayer/audiodevice.h @@ -0,0 +1,71 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef AUDIODEVICE_H +#define AUDIODEVICE_H + + +#include + + +class AudioDevicePrivate; + + +class AudioDevice : public QObject { + Q_OBJECT +public: + AudioDevice( unsigned int freq = 44000, unsigned int channels = 2, unsigned int bytesPerSample = 2 ); + ~AudioDevice(); + + unsigned int canWrite() const; + void write( char *buffer, unsigned int length ); + int bytesWritten(); + + unsigned int channels() const; + unsigned int frequency() const; + unsigned int bytesPerSample() const; + unsigned int bufferSize() const; + + // Each volume level is from 0 to 0xFFFF + static void getVolume( unsigned int& left, unsigned int& right, bool& muted ); + static void setVolume( unsigned int left, unsigned int right, bool muted ); + + static unsigned int leftVolume() { bool muted; unsigned int l, r; getVolume( l, r, muted ); return l; } + static unsigned int rightVolume() { bool muted; unsigned int l, r; getVolume( l, r, muted ); return r; } + static bool isMuted() { bool muted; unsigned int l, r; getVolume( l, r, muted ); return muted; } + + static void increaseVolume() { setVolume( leftVolume() + 1968, rightVolume() + 1968, isMuted() ); } + static void decreaseVolume() { setVolume( leftVolume() - 1966, rightVolume() - 1966, isMuted() ); } + +public slots: + // Convinence functions derived from above functions + void setVolume( unsigned int level ) { setVolume( level, level, isMuted() ); } + void mute() { setVolume( leftVolume(), rightVolume(), TRUE ); } + void volumeChanged( bool muted ); + +signals: + void completedIO(); + +private: + AudioDevicePrivate *d; +}; + + +#endif // AUDIODEVICE_H + diff --git a/core/multimedia/opieplayer/audiowidget.cpp b/core/multimedia/opieplayer/audiowidget.cpp new file mode 100644 index 0000000..243c58c --- a/dev/null +++ b/core/multimedia/opieplayer/audiowidget.cpp @@ -0,0 +1,277 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "audiowidget.h" +#include "mediaplayerstate.h" + + +extern MediaPlayerState *mediaPlayerState; + + +static const int xo = -2; // movable x offset +static const int yo = 22; // movable y offset + + +struct MediaButton { + int xPos, yPos; + int color; + bool isToggle, isBig, isHeld, isDown; +}; + + +// Layout information for the audioButtons (and if it is a toggle button or not) +MediaButton audioButtons[] = { + { 3*30-15+xo, 3*30-13+yo, 0, TRUE, TRUE, FALSE, FALSE }, // play + { 1*30+xo, 5*30+yo, 2, FALSE, FALSE, FALSE, FALSE }, // stop + { 5*30+xo, 5*30+yo, 2, TRUE, FALSE, FALSE, FALSE }, // pause + { 6*30-5+xo, 3*30+yo, 1, FALSE, FALSE, FALSE, FALSE }, // next + { 0*30+5+xo, 3*30+yo, 1, FALSE, FALSE, FALSE, FALSE }, // previous + { 3*30+xo, 0*30+5+yo, 3, FALSE, FALSE, FALSE, FALSE }, // volume up + { 3*30+xo, 6*30-5+yo, 3, FALSE, FALSE, FALSE, FALSE }, // volume down + { 5*30+xo, 1*30+yo, 0, TRUE, FALSE, FALSE, FALSE }, // repeat/loop + { 1*30+xo, 1*30+yo, 0, FALSE, FALSE, FALSE, FALSE } // playlist +}; + + +static const int numButtons = (sizeof(audioButtons)/sizeof(MediaButton)); + + +AudioWidget::AudioWidget(QWidget* parent, const char* name, WFlags f) : + QWidget( parent, name, f ) +{ + setCaption( tr("MediaPlayer") ); + setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) ); + pixmaps[0] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButtonsAll" ) ); + pixmaps[1] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButtonsBig" ) ); + pixmaps[2] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaControls" ) ); + pixmaps[3] = new QPixmap( Resource::loadPixmap( "mpegplayer/animatedButton" ) ); + + songInfo = new Ticker( this ); + songInfo->setFocusPolicy( QWidget::NoFocus ); + songInfo->setGeometry( QRect( 7, 3, 220, 20 ) ); + + slider = new QSlider( Qt::Horizontal, this ); + slider->setFixedWidth( 220 ); + slider->setFixedHeight( 20 ); + slider->setMinValue( 0 ); + slider->setMaxValue( 1 ); + slider->setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) ); + slider->setFocusPolicy( QWidget::NoFocus ); + slider->setGeometry( QRect( 7, 262, 220, 20 ) ); + + connect( slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) ); + connect( slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) ); + + connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) ); + connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) ); + connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) ); + connect( mediaPlayerState, SIGNAL( viewChanged(char) ), this, SLOT( setView(char) ) ); + connect( mediaPlayerState, SIGNAL( loopingToggled(bool) ), this, SLOT( setLooping(bool) ) ); + connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( setPaused(bool) ) ); + connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) ); + + // Intialise state + setLength( mediaPlayerState->length() ); + setPosition( mediaPlayerState->position() ); + setLooping( mediaPlayerState->fullscreen() ); + setPaused( mediaPlayerState->paused() ); + setPlaying( mediaPlayerState->playing() ); + +} + + +AudioWidget::~AudioWidget() { + for ( int i = 0; i < 4; i++ ) + delete pixmaps[i]; +} + + +static bool audioSliderBeingMoved = FALSE; + + +void AudioWidget::sliderPressed() { + audioSliderBeingMoved = TRUE; +} + + +void AudioWidget::sliderReleased() { + audioSliderBeingMoved = FALSE; + if ( slider->width() == 0 ) + return; + long val = long((double)slider->value() * mediaPlayerState->length() / slider->width()); + mediaPlayerState->setPosition( val ); +} + + +void AudioWidget::setPosition( long i ) { + updateSlider( i, mediaPlayerState->length() ); +} + + +void AudioWidget::setLength( long max ) { + updateSlider( mediaPlayerState->position(), max ); +} + + +void AudioWidget::setView( char view ) { + if ( view == 'a' ) { + startTimer( 150 ); + showMaximized(); + } else { + killTimers(); + hide(); + } +} + + +void AudioWidget::updateSlider( long i, long max ) { + if ( max == 0 ) + return; + // Will flicker too much if we don't do this + // Scale to something reasonable + int width = slider->width(); + int val = int((double)i * width / max); + if ( !audioSliderBeingMoved ) { + if ( slider->value() != val ) + slider->setValue( val ); + if ( slider->maxValue() != width ) + slider->setMaxValue( width ); + } +} + + +void AudioWidget::setToggleButton( int i, bool down ) { + if ( down != audioButtons[i].isDown ) + toggleButton( i ); +} + + +void AudioWidget::toggleButton( int i ) { + audioButtons[i].isDown = !audioButtons[i].isDown; + QPainter p(this); + paintButton ( &p, i ); +} + + +void AudioWidget::paintButton( QPainter *p, int i ) { + int x = audioButtons[i].xPos; + int y = audioButtons[i].yPos; + int offset = 22 + 14 * audioButtons[i].isBig + audioButtons[i].isDown; + int buttonSize = 64 + audioButtons[i].isBig * (90 - 64); + p->drawPixmap( x, y, *pixmaps[audioButtons[i].isBig], buttonSize * (audioButtons[i].isDown + 2 * audioButtons[i].color), 0, buttonSize, buttonSize ); + p->drawPixmap( x + offset, y + offset, *pixmaps[2], 18 * i, 0, 18, 18 ); +} + + +void AudioWidget::timerEvent( QTimerEvent * ) { + static int frame = 0; + if ( !mediaPlayerState->paused() && audioButtons[ AudioPlay ].isDown ) { + frame = frame >= 7 ? 0 : frame + 1; + int x = audioButtons[AudioPlay].xPos; + int y = audioButtons[AudioPlay].yPos; + QPainter p( this ); + // Optimize to only draw the little bit of the changing images which is different + p.drawPixmap( x + 14, y + 8, *pixmaps[3], 32 * frame, 0, 32, 32 ); + p.drawPixmap( x + 37, y + 37, *pixmaps[2], 18 * AudioPlay, 0, 6, 3 ); + } +} + + +void AudioWidget::mouseMoveEvent( QMouseEvent *event ) { + for ( int i = 0; i < numButtons; i++ ) { + int size = audioButtons[i].isBig; + int x = audioButtons[i].xPos; + int y = audioButtons[i].yPos; + if ( event->state() == QMouseEvent::LeftButton ) { + // The test to see if the mouse click is inside the circular button or not + // (compared with the radius squared to avoid a square-root of our distance) + int radius = 32 + 13 * size; + QPoint center = QPoint( x + radius, y + radius ); + QPoint dXY = center - event->pos(); + int dist = dXY.x() * dXY.x() + dXY.y() * dXY.y(); + bool isOnButton = dist <= (radius * radius); +// QRect r( x, y, 64 + 22*size, 64 + 22*size ); +// bool isOnButton = r.contains( event->pos() ); // Rectangular Button code + if ( isOnButton && !audioButtons[i].isHeld ) { + audioButtons[i].isHeld = TRUE; + toggleButton(i); + switch (i) { + case AudioVolumeUp: emit moreClicked(); return; + case AudioVolumeDown: emit lessClicked(); return; + } + } else if ( !isOnButton && audioButtons[i].isHeld ) { + audioButtons[i].isHeld = FALSE; + toggleButton(i); + } + } else { + if ( audioButtons[i].isHeld ) { + audioButtons[i].isHeld = FALSE; + if ( !audioButtons[i].isToggle ) + setToggleButton( i, FALSE ); + switch (i) { + case AudioPlay: mediaPlayerState->setPlaying(audioButtons[i].isDown); return; + case AudioStop: mediaPlayerState->setPlaying(FALSE); return; + case AudioPause: mediaPlayerState->setPaused(audioButtons[i].isDown); return; + case AudioNext: mediaPlayerState->setNext(); return; + case AudioPrevious: mediaPlayerState->setPrev(); return; + case AudioLoop: mediaPlayerState->setLooping(audioButtons[i].isDown); return; + case AudioVolumeUp: emit moreReleased(); return; + case AudioVolumeDown: emit lessReleased(); return; + case AudioPlayList: mediaPlayerState->setList(); return; + } + } + } + } +} + + +void AudioWidget::mousePressEvent( QMouseEvent *event ) { + mouseMoveEvent( event ); +} + + +void AudioWidget::mouseReleaseEvent( QMouseEvent *event ) { + mouseMoveEvent( event ); +} + + +void AudioWidget::showEvent( QShowEvent* ) { + QMouseEvent event( QEvent::MouseMove, QPoint( 0, 0 ), 0, 0 ); + mouseMoveEvent( &event ); +} + + +void AudioWidget::closeEvent( QCloseEvent* ) { + mediaPlayerState->setList(); +} + + +void AudioWidget::paintEvent( QPaintEvent * ) { + QPainter p( this ); + for ( int i = 0; i < numButtons; i++ ) + paintButton( &p, i ); +} + + diff --git a/core/multimedia/opieplayer/audiowidget.h b/core/multimedia/opieplayer/audiowidget.h new file mode 100644 index 0000000..4b82a91 --- a/dev/null +++ b/core/multimedia/opieplayer/audiowidget.h @@ -0,0 +1,144 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef AUDIO_WIDGET_H +#define AUDIO_WIDGET_H + + +#include +#include +#include +#include +#include +#include +#include + + +class QPixmap; + + +enum AudioButtons { + AudioPlay, + AudioStop, + AudioPause, + AudioNext, + AudioPrevious, + AudioVolumeUp, + AudioVolumeDown, + AudioLoop, + AudioPlayList +}; + + +#define USE_DBLBUF + + +class Ticker : public QFrame { + Q_OBJECT +public: + Ticker( QWidget* parent=0 ) : QFrame( parent ) { + setFrameStyle( WinPanel | Sunken ); + setText( "No Song" ); + } + ~Ticker() { } + void setText( const QString& text ) { + pos = 0; // reset it everytime the text is changed + scrollText = text; + pixelLen = fontMetrics().width( scrollText ); + killTimers(); + if ( pixelLen > width() ) + startTimer( 50 ); + update(); + } +protected: + void timerEvent( QTimerEvent * ) { + pos = ( pos + 1 > pixelLen ) ? 0 : pos + 1; +#ifndef USE_DBLBUF + scroll( -1, 0, contentsRect() ); +#else + repaint( FALSE ); +#endif + } + void drawContents( QPainter *p ) { +#ifndef USE_DBLBUF + for ( int i = 0; i - pos < width() && (i < 1 || pixelLen > width()); i += pixelLen ) + p->drawText( i - pos, 0, INT_MAX, height(), AlignVCenter, scrollText ); +#else + // Double buffering code. + // Looks like qvfb makes it look like it flickers but I don't think it really is + QPixmap pm( width(), height() ); + pm.fill( colorGroup().base() ); + QPainter pmp( &pm ); + for ( int i = 0; i - pos < width() && (i < 1 || pixelLen > width()); i += pixelLen ) + pmp.drawText( i - pos, 0, INT_MAX, height(), AlignVCenter, scrollText ); + p->drawPixmap( 0, 0, pm ); +#endif + } +private: + QString scrollText; + int pos, pixelLen; +}; + + +class AudioWidget : public QWidget { + Q_OBJECT +public: + AudioWidget( QWidget* parent=0, const char* name=0, WFlags f=0 ); + ~AudioWidget(); + void setTickerText( const QString &text ) { songInfo->setText( text ); } + +public slots: + void updateSlider( long, long ); + void sliderPressed( ); + void sliderReleased( ); + void setPaused( bool b) { setToggleButton( AudioPause, b ); } + void setLooping( bool b) { setToggleButton( AudioLoop, b ); } + void setPlaying( bool b) { setToggleButton( AudioPlay, b ); } + void setPosition( long ); + void setLength( long ); + void setView( char ); + +signals: + void moreClicked(); + void lessClicked(); + void moreReleased(); + void lessReleased(); + void sliderMoved(long); + +protected: + void paintEvent( QPaintEvent *pe ); + void showEvent( QShowEvent *se ); + void mouseMoveEvent( QMouseEvent *event ); + void mousePressEvent( QMouseEvent *event ); + void mouseReleaseEvent( QMouseEvent *event ); + void timerEvent( QTimerEvent *event ); + void closeEvent( QCloseEvent *event ); + +private: + void toggleButton( int ); + void setToggleButton( int, bool ); + void paintButton( QPainter *p, int i ); + QPixmap *pixmaps[4]; + Ticker *songInfo; + QSlider *slider; +}; + + +#endif // AUDIO_WIDGET_H + diff --git a/core/multimedia/opieplayer/libflash/Makefile.in b/core/multimedia/opieplayer/libflash/Makefile.in new file mode 100644 index 0000000..52c8557 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/Makefile.in @@ -0,0 +1,644 @@ +############################################################################# + +####### Compiler, tools and options + +CXX = $(SYSCONF_CXX) $(QT_CXX_MT) +CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) +CC = $(SYSCONF_CC) $(QT_C_MT) +CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) +INCPATH = -I$(QPEDIR)/include +LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) +LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP) +MOC = $(SYSCONF_MOC) +UIC = $(SYSCONF_UIC) + +####### Target + +DESTDIR = ../../plugins/codecs/ +VER_MAJ = 1 +VER_MIN = 0 +VER_PATCH = 0 +TARGET = flashplugin +TARGET1 = lib$(TARGET).so.$(VER_MAJ) + +####### Files + +HEADERS = libflashplugin.h \ + libflashpluginimpl.h +SOURCES = libflashplugin.cpp \ + libflashpluginimpl.cpp \ + adpcm.cc \ + character.cc \ + flash.cc \ + graphic16.cc \ + matrix.cc \ + script.cc \ + sprite.cc \ + bitmap.cc \ + cxform.cc \ + font.cc \ + graphic24.cc \ + movie.cc \ + shape.cc \ + sqrt.cc \ + button.cc \ + displaylist.cc \ + graphic.cc \ + graphic32.cc \ + program.cc \ + sound.cc \ + text.cc +OBJECTS = libflashplugin.o \ + libflashpluginimpl.o \ + adpcm.o \ + character.o \ + flash.o \ + graphic16.o \ + matrix.o \ + script.o \ + sprite.o \ + bitmap.o \ + cxform.o \ + font.o \ + graphic24.o \ + movie.o \ + shape.o \ + sqrt.o \ + button.o \ + displaylist.o \ + graphic.o \ + graphic32.o \ + program.o \ + sound.o \ + text.o +INTERFACES = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = + + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + + +all: $(DESTDIR)$(SYSCONF_LINK_TARGET) + +$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) + $(SYSCONF_LINK_LIB) + +moc: $(SRCMOC) + +tmake: Makefile.in + +Makefile.in: libflash.pro + tmake libflash.pro -o Makefile.in + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) + -rm -f *~ core + -rm -f allmoc.cpp + +####### Extension Modules + +listpromodules: + @echo + +listallmodules: + @echo + +listaddonpromodules: + @echo + +listaddonentmodules: + @echo + + +REQUIRES= + +####### Sub-libraries + + +###### Combined headers + + + +####### Compile + +libflashplugin.o: libflashplugin.cpp \ + libflashplugin.h \ + flash.h \ + ../mediaplayerplugininterface.h + +libflashpluginimpl.o: libflashpluginimpl.cpp \ + libflashplugin.h \ + flash.h \ + ../mediaplayerplugininterface.h \ + libflashpluginimpl.h \ + ../mediaplayerplugininterface.h + +adpcm.o: adpcm.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +character.o: character.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +flash.o: flash.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h \ + graphic16.h \ + graphic24.h \ + graphic32.h + +graphic16.o: graphic16.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h \ + graphic16.h + +matrix.o: matrix.cc \ + matrix.h + +script.o: script.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +sprite.o: sprite.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +bitmap.o: bitmap.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +cxform.o: cxform.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +font.o: font.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +graphic24.o: graphic24.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h \ + graphic24.h + +movie.o: movie.cc \ + movie.h \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h + +shape.o: shape.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +sqrt.o: sqrt.cc + +button.o: button.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +displaylist.o: displaylist.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +graphic.o: graphic.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +graphic32.o: graphic32.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h \ + graphic32.h + +program.o: program.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +sound.o: sound.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +text.o: text.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + + diff --git a/core/multimedia/opieplayer/libflash/README b/core/multimedia/opieplayer/libflash/README new file mode 100644 index 0000000..9914a00 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/README @@ -0,0 +1,191 @@ + +MODIFICATIONS BY TROLLTECH +-------------------------- + +Oct. 2001 + +Just the Lib directory of the flash library source archive +has been copied in to the QPE CVS tree. For the full source code +to create a KDE screensaver or stand alone player etc, download +the orginal source tar ball from http://www.swift-tools.com/Flash +The files libflashplugin* have been added to wrapper the library +to produce a Qtopia Media Player plugin out of the code. + +John R. + + +INTRODUCTION +------------ + +Jun. 12th 2000 + +This the Version 0.4.10 of the Flash Library for Linux. + +Flash Plugin is under GPL, see COPYING file. + +Provides: +- Lib contains the FlashLib sources. +- Plugin contains plugin sources. +- Player contains the standalone player sources. +- Kflash a Flash KDE screen saver. + +New features: +- Bug fixes. +- 24 and 32 modes supported. +- Flash Library as screen saver (for xcreensaver and KDE). + +To get some information on this library check out the following link : +http://www.swift-tools.com/Flash + +Authors: Olivier Debon + Fabrice Bellard + +FEATURES +-------- + +Limitations : + - The plugin and the player use XShm extensions, so remote display is not possible. + - No Flash 4 features (but no crash on Flash 4 files). + +Not functional : + - No Morphing. + - No vertical anti-aliasing. + +SOUND SUPPORT +------------- + +Limitations : + - No streamed sound supported (interleaved data). + - No sound envelop. So no fading or balancing effect. + +But the main feature is here and sound can be enjoyed. + +I recommend OSS drivers, but it is not required at all +(http://www.opensound.com) + +If you have troubles with sound put the -DNOSOUND option +for compilation. Also do this for non-Linux Unix. + +THE PLAYER +---------- + +The standalone player can simply control movie by +pressing Q to quit, P to pause, C to continue and +R to replay. +There is also the possibility to zoom in or out +and scroll using Keypad +/- and cursor keys, but +it is buggy on frozen images. + +THE SCREEN SAVERS +----------------- + +The standalone player can be run though xscreensaver. Modify +your .xscreensaver file to add swfplayer: +programs: swfplayer -root /home/olivier/Flash/Test/test.swf +(See xscreensaver doc for more details on Xscreensaver). + +For KDE, just install the kflash.kss file from the Kflash +directory in /usr/bin (or where your KDE installation expects +kss file to be). +In your KDE start menu, select Settings->Desktop->Screensaver +Choose 'Flash Movies' and click on SetUp button. You'll have +to select a Flash file (take the test.swf file provided with +this distribution). The fullscreen option will scale the movie +to the entire screen (it can be very CPU intensive). The +enable sound option will allow to play sounds, but as a screen +saver mode this is not a good idea :) + +BUG REPORT +---------- + +If Netscape crashes when it started to play a Flash file, please +report the complete url where you have found the file. +Do not send the actual file ! + +If you have rendering problem also report the url. + +If the plugin does not seem to show anything or does not do what it +is supposed to do, please consider that the plugin does not support +all Flash 2/4 features. Anyway it tries to play it but may fail then. + +COMPILATION +----------- + +If you use Linux just type 'make'. + +Warning : the plugin compilation should not fail, but you may +have problem with Netscape at startup. See INSTALLATION section +for workarounds. + +For other Unices like FreeBSD or Solaris you may have to change +some flags. See Plugin/Makefile for hints. + +INSTALLATION +------------ + +Once you have successfully compiled the plugin, put the file +npflash.so (located in the Plugin directory) into your +~/.netscape/plugins directory or into the system-wide +/opt/netscape/plugins directory (depends on where you have installed +Netscape). + +If Netscape already runs type 'javascript:navigator.plugins.refresh' +in the Location field. + + PROBLEMS + -------- + +If you have problem to successfully install the plugin, please +read the following hints. Otherwise, report the problem with full +description of your configuration : +- Distribution. +- Compiler. +- Libs (the output of ldconfig -p is useful). +- The netscape version and the output of 'ldd netscape'. + +If some symbols like _rtti or _throw are unresolved, it seems +that you have egcs. Just uncomment the proper line in the main +Makefile. +You may then still have some unresolved symbols like __sigsetjmp. +This time, add -DC6R5 in the Plugin/Makefile at the PLUGIN_DEFINES +line. + + CHECKING + -------- + +To verify that the plugin is installed properly, type "about:plugins" +in Netscape's "Location:" or "Netsite:" field. The plugin should show +up there, something like + +___________________________________________________________________________ + + Shockwave Flash + + File name: /opt/netscape/plugins/npflash.so + + Flash file player Version 0.4.10 + + Shockwave is a trademark of MacromediaŽ + + Author: Olivier Debon + + --------------------------------------------------------------------------------- +| Mime Type | Description | Suffixes | Enabled | +|--------------------------------+-------------------+-------------+--------------| +| application/futuresplash | Flash Plugin | spl | Yes | +| application/x-shockwave-flash | | swf | Yes | + --------------------------------------------------------------------------------- + +___________________________________________________________________________ + + +If it shows up, but the "Enabled" column says "No", you need to +configure the Flash plugin as a helper application. Go to +Edit/Preferences/Navigator/Applications, and add it as follows: + +Description: Flash Plugin +MIME Type: application/x-shockwave-flash +Suffixes: swf +Handled By: Plug In (select "Shockwave Flash") + +------ diff --git a/core/multimedia/opieplayer/libflash/adpcm.cc b/core/multimedia/opieplayer/libflash/adpcm.cc new file mode 100644 index 0000000..a4bc435 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/adpcm.cc @@ -0,0 +1,235 @@ + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +// This file has been rearranged from the code posted +// on news:forums.macromedia.com by Jonathan Gay. +// Courtesy of Macromedia + +// +// ADPCM tables +// + +static const int indexTable2[2] = { + -1, 2, +}; + +// Is this ok? +static const int indexTable3[4] = { + -1, -1, 2, 4, +}; + +static const int indexTable4[8] = { + -1, -1, -1, -1, 2, 4, 6, 8, +}; + +static const int indexTable5[16] = { + -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16, +}; + +static const int* indexTables[] = { + indexTable2, + indexTable3, + indexTable4, + indexTable5 +}; + +static const int stepsizeTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +long +Adpcm::GetBits(int n) +{ + if ( bitPos < n ) FillBuffer(); + + assert(bitPos >= n); + + long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n); + bitPos -= n; + + return v; +} + +long +Adpcm::GetSBits(int n) +{ + if ( bitPos < n ) FillBuffer(); + + assert(bitPos >= n); + + long v = ((long)bitBuf << (32-bitPos)) >> (32-n); + bitPos -= n; + + return v; +} + +// +// The Decompressor +// + +// Constructor +Adpcm::Adpcm(unsigned char *buffer, long isStereo) +{ + stereo = isStereo; + src = buffer; + + nBits = 0; // flag that it is not inited + nSamples = 0; + + bitPos = 0; + bitBuf = 0; +} + +void +Adpcm::FillBuffer() +{ + while ( bitPos <= 24 /*&& srcSize > 0*/ ) { + bitBuf = (bitBuf<<8) | *src++; + bitPos += 8; + } +} + +void +Adpcm::Decompress(short *dst, long n) +{ + if ( nBits == 0 ) { + // Get the compression header + nBits = (int)GetBits(2)+2; + } + + const int* indexTable = indexTables[nBits-2]; + int k0 = 1 << (nBits-2); + int signmask = 1 << (nBits-1); + + if ( !stereo ) { + // Optimize for mono + long vp = valpred[0]; // maybe these can get into registers... + int ind = index[0]; + long ns = nSamples; + + while ( n-- > 0 ) { + ns++; + + if ( (ns & 0xFFF) == 1 ) { + // Get a new block header + *dst++ = (short)(vp = GetSBits(16)); + + ind = (int)GetBits(6); // The first sample in a block does not have a delta + } else { + // Process a delta value + int delta = (int)GetBits(nBits); + + // Compute difference and new predicted value + // Computes 'vpdiff = (delta+0.5)*step/4' + int step = stepsizeTable[ind]; + long vpdiff = 0; + int k = k0; + + do { + if ( delta & k ) + vpdiff += step; + step >>= 1; + k >>= 1; + } while ( k ); + + vpdiff += step; // add 0.5 + + if ( delta & signmask ) // the sign bit + vp -= vpdiff; + else + vp += vpdiff; + + // Find new index value + ind += indexTable[delta&(~signmask)]; + + if ( ind < 0 ) + ind = 0; + else if ( ind > 88 ) + ind = 88; + + // clamp output value + if ( vp != (short)vp ) + vp = vp < 0 ? -32768 : 32767; + + /* Step 7 - Output value */ + *dst++ = (short)vp; + } + } + + valpred[0] = vp; + index[0] = ind; + nSamples = ns; + + } else { + int sn = stereo ? 2 : 1; + + // Stereo + while ( n-- > 0 ) { + + nSamples++; + + if ( (nSamples & 0xFFF) == 1 ) { + // Get a new block header + for ( int i = 0; i < sn; i++ ) { + + *dst++ = (short)(valpred[i] = GetSBits(16)); + + // The first sample in a block does not have a delta + index[i] = (int)GetBits(6); + } + } else { + // Process a delta value + for ( int i = 0; i < sn; i++ ) { + int delta = (int)GetBits(nBits); + + // Compute difference and new predicted value + // Computes 'vpdiff = (delta+0.5)*step/4' + + int step = stepsizeTable[index[i]]; + long vpdiff = 0; + int k = k0; + + do { + if ( delta & k ) vpdiff += step; + step >>= 1; + k >>= 1; + } while ( k ); + vpdiff += step; // add 0.5 + + + if ( delta & signmask ) // the sign bit + valpred[i] -= vpdiff; + else + valpred[i] += vpdiff; + + // Find new index value + index[i] += indexTable[delta&(~signmask)]; + + if ( index[i] < 0 ) + index[i] = 0; + else if ( index[i] > 88 ) + index[i] = 88; + + // clamp output value + if ( valpred[i] != (short)valpred[i] ) + valpred[i] = valpred[i] < 0 ? -32768 : 32767; + + /* Step 7 - Output value */ + *dst++ = (short)valpred[i]; + } + } + } + } +} diff --git a/core/multimedia/opieplayer/libflash/adpcm.h b/core/multimedia/opieplayer/libflash/adpcm.h new file mode 100644 index 0000000..5714c0c --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/adpcm.h @@ -0,0 +1,36 @@ +#ifndef _ADPCM_H_ +#define _ADPCM_H_ + +class Adpcm { + + // Destination format - note we always decompress to 16 bit + long stereo; + int nBits; // number of bits in each sample + + long valpred[2]; // Current state + int index[2]; + + long nSamples; // number of samples decompressed so far + + // Parsing Info + unsigned char *src; + long bitBuf; // this should always contain at least 24 bits of data + int bitPos; + + void FillBuffer(); + + long GetBits(int n); + + long GetSBits(int n); + +public: + Adpcm(unsigned char *buffer, long isStereo); + + void Decompress(short * dst, long n); // return number of good samples +#ifdef DUMP + void dump(BitStream *bs); + void Compress(short *pcm, long n, int bits); +#endif +}; + +#endif /* _ADPCM_H_ */ diff --git a/core/multimedia/opieplayer/libflash/bitmap.cc b/core/multimedia/opieplayer/libflash/bitmap.cc new file mode 100644 index 0000000..03b4588 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/bitmap.cc @@ -0,0 +1,606 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +static unsigned char *inputData; + +// Class variables + +int Bitmap::haveTables = 0; + +struct jpeg_decompress_struct Bitmap::jpegObject; + +struct jpeg_source_mgr Bitmap::jpegSourceManager; + +MyErrorHandler Bitmap::jpegErrorMgr; + +Bitmap::Bitmap(long id, int level) : Character(BitmapType, id ) +{ + pixels = NULL; + alpha_buf = NULL; + colormap = NULL; + nbColors = 0; + defLevel = level; +} + +Bitmap::~Bitmap() +{ + if (pixels) { + delete[] pixels; + } + if (alpha_buf) { + delete[] alpha_buf; + } + if (colormap) + { + delete colormap; + } + if (haveTables) { + jpeg_destroy_decompress(&jpegObject); + haveTables = 0; + } +} + +static void errorExit(j_common_ptr info) +{ + (*info->err->output_message) (info); + longjmp(((MyErrorHandler *)info->err)->setjmp_buffer, 1); +} + +// Methods for Source data manager +static void initSource(struct jpeg_decompress_struct *cInfo) +{ + cInfo->src->bytes_in_buffer = 0; +} + +static boolean fillInputBuffer(struct jpeg_decompress_struct *cInfo) +{ + cInfo->src->next_input_byte = inputData; + cInfo->src->bytes_in_buffer = 1; + inputData++; + + return 1; +} + +static void skipInputData(struct jpeg_decompress_struct *cInfo, long count) +{ + cInfo->src->bytes_in_buffer = 0; + inputData += count; +} + +static boolean resyncToRestart(struct jpeg_decompress_struct *cInfo, int desired) +{ + return jpeg_resync_to_restart(cInfo, desired); +} + +static void termSource(struct jpeg_decompress_struct *cInfo) +{ +} + +long Bitmap::getWidth() +{ + return width; +} + +long Bitmap::getHeight() +{ + return height; +} + +Color * +Bitmap::getColormap(long *n) { + if (n) *n = nbColors; + return colormap; +} + +unsigned char * +Bitmap::getPixels() +{ + return pixels; +} + +// Read Tables and Compressed data to produce an image + +static int +buildJpegAlpha(Bitmap *b, unsigned char *buffer) +{ + z_stream stream; + int status; + unsigned char *data; + + data = new unsigned char[b->width*b->height]; + if (data == NULL) + return -1; + + stream.next_in = buffer; + stream.avail_in = 1; + stream.next_out = data; + stream.avail_out = b->width*b->height; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + + status = inflateInit(&stream); + + while (1) { + status = inflate(&stream, Z_SYNC_FLUSH) ; + if (status == Z_STREAM_END) { + break; + } + if (status != Z_OK) { + printf("Zlib data error : %s\n", stream.msg); + delete data; + return -1; + } + stream.avail_in = 1; + } + + inflateEnd(&stream); + + b->alpha_buf = data; + + return 0; +} + +int +Bitmap::buildFromJpegInterchangeData(unsigned char *stream, int read_alpha, long offset) +{ + struct jpeg_decompress_struct cInfo; + struct jpeg_source_mgr mySrcMgr; + MyErrorHandler errorMgr; + JSAMPROW buffer[1]; + unsigned char *ptrPix; + int stride; + long n; + +#if PRINT&1 + printf("flash: loading jpeg (interchange)\n"); +#endif + + // Kludge to correct some corrupted files + if (stream[1] == 0xd9 && stream[3] == 0xd8) { + stream[3] = 0xd9; + stream[1] = 0xd8; + } + + // Setup error handler + cInfo.err = jpeg_std_error(&errorMgr.pub); + errorMgr.pub.error_exit = errorExit; + + if (setjmp(errorMgr.setjmp_buffer)) { + // JPEG data Error + jpeg_destroy_decompress(&cInfo); + if (pixels) { + delete[] pixels; + pixels = NULL; + } + return -1; + } + + // Set current stream pointer to stream + inputData = stream; + + // Here it's Ok + + jpeg_create_decompress(&cInfo); + + // Setup source manager structure + mySrcMgr.init_source = initSource; + mySrcMgr.fill_input_buffer = fillInputBuffer; + mySrcMgr.skip_input_data = skipInputData; + mySrcMgr.resync_to_restart = resyncToRestart; + mySrcMgr.term_source = termSource; + + // Set default source manager + cInfo.src = &mySrcMgr; + + jpeg_read_header(&cInfo, FALSE); + + jpeg_read_header(&cInfo, TRUE); + cInfo.quantize_colors = TRUE; // Create colormapped image + jpeg_start_decompress(&cInfo); + + // Set objet dimensions + height = cInfo.output_height; + width = cInfo.output_width; + bpl = width; + pixels = new unsigned char [height*width]; + if (pixels == NULL) { + jpeg_finish_decompress(&cInfo); + jpeg_destroy_decompress(&cInfo); + return -1; + } + ptrPix = pixels; + + stride = cInfo.output_width * cInfo.output_components; + + buffer[0] = (JSAMPROW)malloc(stride); + + while (cInfo.output_scanline < cInfo.output_height) { + + jpeg_read_scanlines(&cInfo, buffer, 1); + + memcpy(ptrPix,buffer[0],stride); + + ptrPix+= stride; + } + + free(buffer[0]); + + colormap = new Color[cInfo.actual_number_of_colors]; + if (colormap == NULL) { + delete pixels; + jpeg_finish_decompress(&cInfo); + jpeg_destroy_decompress(&cInfo); + return -1; + } + nbColors = cInfo.actual_number_of_colors; + + for(n=0; n < nbColors; n++) + { + colormap[n].red = cInfo.colormap[0][n]; + colormap[n].green = cInfo.colormap[1][n]; + colormap[n].blue = cInfo.colormap[2][n]; + } + + jpeg_finish_decompress(&cInfo); + jpeg_destroy_decompress(&cInfo); + + if (read_alpha) { + if (buildJpegAlpha(this, stream + offset) < 0) { + return -1; + } + } + return 0; +} + +// Read JPEG image using pre-loaded Tables + +int +Bitmap::buildFromJpegAbbreviatedData(unsigned char *stream) +{ + JSAMPROW buffer[1]; + unsigned char *ptrPix; + int stride; + long n; + int status; + +#if PRINT&1 + printf("flash: loading jpeg (abbreviated)\n"); +#endif + + // Set current stream pointer to stream + inputData = stream; + + // Error handler + if (setjmp(jpegErrorMgr.setjmp_buffer)) { + // JPEG data Error + //jpeg_destroy_decompress(&jpegObject); + if (pixels) { + delete[] pixels; + pixels = NULL; + } + return -1; + } + + // Here it's ok + + jpeg_read_header(&jpegObject, TRUE); + jpegObject.quantize_colors = TRUE; // Create colormapped image + jpeg_start_decompress(&jpegObject); + + // Set objet dimensions + height = jpegObject.output_height; + width = jpegObject.output_width; + bpl = width; + pixels = new unsigned char [height*width]; + if (pixels == NULL) { + jpeg_finish_decompress(&jpegObject); + return -1; + } + ptrPix = pixels; + + stride = jpegObject.output_width * jpegObject.output_components; + + buffer[0] = (JSAMPROW)malloc(stride); + + while (jpegObject.output_scanline < jpegObject.output_height) { + + status = jpeg_read_scanlines(&jpegObject, buffer, 1); + + memcpy(ptrPix,buffer[0],stride); + + ptrPix+= stride; + } + + free(buffer[0]); + + colormap = new Color[jpegObject.actual_number_of_colors]; + if (colormap == NULL) { + jpeg_finish_decompress(&jpegObject); + delete pixels; + return -1; + } + nbColors = jpegObject.actual_number_of_colors; + + for(n=0; n < nbColors; n++) + { + colormap[n].red = jpegObject.colormap[0][n]; + colormap[n].green = jpegObject.colormap[1][n]; + colormap[n].blue = jpegObject.colormap[2][n]; + } + + status = jpeg_finish_decompress(&jpegObject); + + return 0; +} + +// Just init JPEG object and read JPEG Tables + +int +Bitmap::readJpegTables(unsigned char *stream) +{ + if (haveTables) { + //Error, it has already been initialized + return -1; + } + + // Setup error handler + jpegObject.err = jpeg_std_error(&jpegErrorMgr.pub); + jpegErrorMgr.pub.error_exit = errorExit; + + if (setjmp(jpegErrorMgr.setjmp_buffer)) { + // JPEG data Error + jpeg_destroy_decompress(&jpegObject); + return -1; + } + + // Set current stream pointer to stream + inputData = stream; + + // Here it's Ok + + jpeg_create_decompress(&jpegObject); + + // Setup source manager structure + jpegSourceManager.init_source = initSource; + jpegSourceManager.fill_input_buffer = fillInputBuffer; + jpegSourceManager.skip_input_data = skipInputData; + jpegSourceManager.resync_to_restart = resyncToRestart; + jpegSourceManager.term_source = termSource; + + // Set default source manager + jpegObject.src = &jpegSourceManager; + + jpeg_read_header(&jpegObject, FALSE); + + haveTables = 1; + + return 0; +} + +int +Bitmap::buildFromZlibData(unsigned char *buffer, int width, int height, int format, int tableSize, int tableHasAlpha) +{ + z_stream stream; + int status; + unsigned char *data; + int elementSize; + +#if PRINT&1 + printf("flash: loading with zlib\n"); +#endif + + this->width = width; + this->height = height; + this->bpl = width; + + if (tableHasAlpha) { + elementSize = 4; // Cmap is RGBA + } else { + elementSize = 3; // Cmap is RGB + } + + stream.next_in = buffer; + stream.avail_in = 1; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + + tableSize++; + + // Uncompress Color Table + if (format == 3) { + unsigned char *colorTable; + long n; + + // Ajust width for 32 bit padding + width = (width+3)/4*4; + this->width = width; + this->bpl = width; + + depth = 1; + colorTable = new unsigned char[tableSize*elementSize]; + if (colorTable == NULL) { + return -1; + } + + stream.next_out = colorTable; + stream.avail_out = tableSize*elementSize; + + inflateInit(&stream); + + while (1) { + status = inflate(&stream, Z_SYNC_FLUSH); + if (status == Z_STREAM_END) { + break; + } + if (status != Z_OK) { + printf("Zlib cmap error : %s\n", stream.msg); + return -1; + } + stream.avail_in = 1; + // Colormap if full + if (stream.avail_out == 0) { + break; + } + } + + nbColors = tableSize; + + colormap = new Color[nbColors]; + if (colormap == NULL) { + delete colorTable; + return -1; + } + + for(n=0; n < nbColors; n++) { + colormap[n].red = colorTable[n*elementSize+0]; + colormap[n].green = colorTable[n*elementSize+1]; + colormap[n].blue = colorTable[n*elementSize+2]; + if (tableHasAlpha) { + colormap[n].alpha = colorTable[n*elementSize+3]; + } + } + + delete colorTable; + + } else if (format == 4) { + depth = 2; + width = (width+1)/2*2; + this->bpl = width; + } else if (format == 5) { + depth = 4; + } + + data = new unsigned char[depth*width*height]; + if (data == NULL) { + if (colormap) delete colormap; + return -1; + } + + stream.next_out = data; + stream.avail_out = depth*width*height; + + if (format != 3) { + status = inflateInit(&stream); + } + + while (1) { + status = inflate(&stream, Z_SYNC_FLUSH) ; + if (status == Z_STREAM_END) { + break; + } + if (status != Z_OK) { + printf("Zlib data error : %s\n", stream.msg); + delete data; + return -1; + } + stream.avail_in = 1; + } + + inflateEnd(&stream); + + pixels = new unsigned char [height*width]; + if (pixels == NULL) { + if (colormap) delete colormap; + delete data; + return -1; + } + + if (format != 3) { + int n,c; + unsigned char r,g,b,a; + unsigned char *ptr; + + r = g = b = a = 0; /* to supress warnings */ + + nbColors = 0; + colormap = new Color[256]; + if (colormap == NULL) { + delete data; + delete pixels; + return -1; + } + memset(colormap, 0, 256 * sizeof(Color)); + ptr = pixels; + + for(n=0; n < width*height*depth; n+=depth,ptr++) { + + switch (format) { + case 4: + a = 1; + r = (data[n] & 0x78)<<1; + g = ((data[n] & 0x03)<<6) | (data[n+1] & 0xc0)>>2; + b = (data[n+1] & 0x1e)<<3; + break; + case 5: + a = data[n]; + // Reduce color dynamic range + r = data[n+1]&0xe0; + g = data[n+2]&0xe0; + b = data[n+3]&0xe0; + break; + } + for(c=0; c < nbColors; c++) { + if (r == colormap[c].red + && g == colormap[c].green + && b == colormap[c].blue) { + *ptr = c; + break; + } + } + if (c == nbColors) { + if (nbColors == 256) continue; + nbColors++; + if (nbColors == 256) { + //printf("Colormap entries exhausted. After %d scanned pixels\n", n/4); + } + colormap[c].alpha = a; + colormap[c].red = r; + colormap[c].green = g; + colormap[c].blue = b; + *ptr = c; + } + } + } else { + memcpy(pixels, data, width*height); + if (tableHasAlpha) { + int n; + unsigned char *ptr, *alpha; + + alpha_buf = (unsigned char *)malloc(width*height); + ptr = data; + alpha = alpha_buf; + for(n=0; n < width*height; n++, ptr++, alpha++) { + *alpha = colormap[*ptr].alpha; + } + } + } + + delete data; + return 0; +} + diff --git a/core/multimedia/opieplayer/libflash/bitmap.h b/core/multimedia/opieplayer/libflash/bitmap.h new file mode 100644 index 0000000..7925309 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/bitmap.h @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _BITMAP_H_ +#define _BITMAP_H_ + +struct MyErrorHandler { + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; + +class Bitmap : public Character { + public: + long width; + long height; + long bpl; + long depth; + + unsigned char *pixels; // Array of Pixels + Color *colormap; // Array of color definitions + long nbColors; + + unsigned char *alpha_buf; // Array of alpha values (no alpha if NULL) + + int defLevel; + +// Class Variables + + static int haveTables; + static struct jpeg_decompress_struct jpegObject; + static struct jpeg_source_mgr jpegSourceManager; + static MyErrorHandler jpegErrorMgr; + +public: + Bitmap(long id, int level = 1); + ~Bitmap(); + + // JPEG handling methods + int buildFromJpegInterchangeData(unsigned char *stream, int alpha, long offset); // Complete + int buildFromJpegAbbreviatedData(unsigned char *stream); // Abbreviated + + // Class Method + static int readJpegTables(unsigned char *stream); // Tables Only + + // ZLIB handling methods + int buildFromZlibData(unsigned char *buffer, + int width, int height, + int format, int tableSize, int tableHasAlpha); + + long getWidth(); + long getHeight(); + Color *getColormap(long *n); + unsigned char *getPixels(); +}; + +#endif /* _BITMAP_H_ */ diff --git a/core/multimedia/opieplayer/libflash/button.cc b/core/multimedia/opieplayer/libflash/button.cc new file mode 100644 index 0000000..7d8369d --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/button.cc @@ -0,0 +1,328 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +// Contructor + +Button::Button(long id, int level) : Character(ButtonType, id) +{ + defLevel = level; + actionRecords = 0; + buttonRecords = 0; + conditionList = 0; + reset(); + isMenu = 0; + sound[0] = sound[1] = sound[2] = sound[3] = 0; +} + +// Destructor + +Button::~Button() +{ + if (actionRecords) { + ActionRecord *ar,*del; + for(ar = actionRecords; ar;) { + del = ar; + ar = ar->next; + delete del; + } + } + if (buttonRecords) { + ButtonRecord *br,*del; + for(br = buttonRecords; br;) { + del = br; + br = br->next; + if (del->cxform) + delete del->cxform; + delete del; + } + } + if (conditionList) { + Condition *cond,*del; + for(cond = conditionList; cond;) { + ActionRecord *ar,*d; + + for(ar = cond->actions; ar;) { + d = ar; + ar = ar->next; + delete d; + } + + del = cond; + cond = cond->next; + delete del; + } + } +} + +ButtonRecord * +Button::getButtonRecords() +{ + return buttonRecords; +} + +ActionRecord * +Button::getActionRecords() +{ + return actionRecords; +} + +Sound ** +Button::getSounds() +{ + return sound; +} + +Condition * +Button::getConditionList() +{ + return conditionList; +} + +void +Button::setButtonSound(Sound *s, int state) +{ + if (state >=0 && state < 4) { + sound[state] = s; + } +} + +void +Button::setButtonMenu(int menu) +{ + isMenu = menu; +} + +void +Button::addButtonRecord( ButtonRecord *br ) +{ +#if 0 + /* SURTOUT PAS !!! */ + ButtonRecord **l; + + /* sort by layer */ + l=&buttonRecords; + while (*l != NULL && (*l)->layer < br->layer) l = &(*l)->next; + br->next = *l; + *l = br; +#else + br->next = 0; + + if (buttonRecords == 0) { + buttonRecords = br; + } else { + ButtonRecord *current; + + for(current = buttonRecords; current->next; current = current->next); + + current->next = br; + } +#endif +} + +void +Button::addCondition( long transition ) +{ + Condition *condition; + + condition = new Condition; + if (condition == NULL) return; + + condition->transition = transition; + condition->next = conditionList; + + // Move current actionRecords to this condition + condition->actions = actionRecords; + actionRecords = 0; + + conditionList = condition; +} + +void +Button::addActionRecord( ActionRecord *ar ) +{ + ar->next = 0; + + if (actionRecords == 0) { + actionRecords = ar; + } else { + ActionRecord *current; + + for(current = actionRecords; current->next; current = current->next); + + current->next = ar; + } +} + +void +Button::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func) +{ + ButtonRecord *br; + + for (br = buttonRecords; br; br = br->next) + { + if ((br->state & stateHitTest) && br->character /* Temporaire */) { + Matrix mat; + + mat = (*matrix) * br->buttonMatrix; + br->character->getRegion(gd, &mat, id, scan_line_func); + } + } +} + +int +Button::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ButtonState renderState) +{ + ButtonRecord *br; + int sprite = 0; + Cxform *cxf = 0; + +#if PRINT==2 + printf("Rendering Button %d for State(s) ", getTagId()); +#endif + for (br = buttonRecords; br; br = br->next) + { + if ((br->state & renderState) && br->character != NULL) { + Matrix mat; + +#if PRINT==2 + printf("%d ", br->state); +#endif + mat = (*matrix) * br->buttonMatrix; + + if (cxform) { + cxf = cxform; + } else if (br->cxform) { + cxf = br->cxform; + } + + if (br->character->execute(gd, &mat, cxf)) { + sprite = 1; + } + } + } +#if PRINT==2 + printf("\n"); +#endif + return sprite; +} + +ActionRecord * +Button::getActionFromTransition(ButtonState cur, ButtonState old) +{ + Condition *cond; + long mask; + + if (old == cur) return NULL; + + /* transitions */ + mask = 0; + if (old == stateUp && cur == stateOver) + mask |= 0x001; + else if (old == stateOver && cur == stateUp) + mask |= 0x002; + else if (old == stateOver && cur == stateDown) + mask |= 0x004; + else if (old == stateDown && cur == stateOver) + mask |= 0x008; + + if (!isMenu) { + /* push button transitions (XXX: not quite correct) */ + if (old == stateDown && cur == stateUp) + mask = 0x010; + else if (old == stateUp && cur == stateDown) + mask = 0x020; + /* XXX: what is transition 0x040 ?? */ + } else { + /* menu button transitions (XXX: not quite correct) */ + if (old == stateUp && cur == stateDown) + mask = 0x080; + else if (old == stateDown && cur == stateUp) + mask = 0x100; + } + + for (cond = conditionList; cond; cond = cond->next) { + if (cond->transition & mask) { + return cond->actions; + } + } + return 0; +} + +void +Button::getBoundingBox(Rect *bbox, DisplayListEntry *e) +{ + ButtonRecord *br; + + bbox->reset(); + for (br = buttonRecords; br; br = br->next) + { + if (br->state & e->renderState) { + if (br->character) { + Rect bb; + + bb.reset(); + br->character->getBoundingBox(&bb,e); + transformBoundingBox(bbox, &br->buttonMatrix, &bb, 0); + } + } + } +} + +/* Get current render character, actually it should be a list of characters + so a DisplayList after all */ +Character * +Button::getRenderCharacter(ButtonState state) +{ + ButtonRecord *br; + + for (br = buttonRecords; br; br = br->next) + { + if (br->state & state) { + return br->character; + } + } + return 0; +} + +void +Button::updateButtonState(DisplayListEntry *e) +{ + ButtonRecord *br; + + e->buttonCharacter = 0; + for (br = buttonRecords; br; br = br->next) + { + if (br->state & e->renderState) { + e->buttonCharacter = br->character; + e->buttonMatrix = br->buttonMatrix; + return; + } + } +} diff --git a/core/multimedia/opieplayer/libflash/button.h b/core/multimedia/opieplayer/libflash/button.h new file mode 100644 index 0000000..75781b2 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/button.h @@ -0,0 +1,88 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _BUTTON_H_ +#define _BUTTON_H_ + +struct ButtonRecord { + ButtonState state; + Character *character; + long layer; + Matrix buttonMatrix; + Cxform *cxform; + + struct ButtonRecord *next; +}; + +struct Condition { + long transition; + ActionRecord *actions; + + Condition *next; +}; + +class Button : public Character { +public: + long defLevel; + + ButtonRecord *buttonRecords; + ActionRecord *actionRecords; + Condition *conditionList; + + long isMenu; + + Sound *sound[4]; + + Button(long id, int level = 1); + ~Button(); + void addActionRecord( ActionRecord *ar ); + void addButtonRecord( ButtonRecord *br ); + void addCondition( long transition ); + int execute(GraphicDevice *gd, Matrix *matrix, + Cxform *cxform, ButtonState renderState); + ActionRecord *getActionFromTransition(ButtonState currentState, + ButtonState old); + void getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func); + ButtonRecord *getButtonRecords(); + void setButtonSound(Sound *, int); + void setButtonMenu(int); + + ActionRecord *getActionRecords(); + Condition *getConditionList(); + Sound **getSounds(); + + void getBoundingBox(Rect *bb, DisplayListEntry *); + + void updateButtonState(DisplayListEntry *); + Character *getRenderCharacter(ButtonState state); + + // Builtin + int isButton() { + return 1; + }; + +#ifdef DUMP + void dump(BitStream *); + void dumpButtonRecords(BitStream *, int putCxform = 0); + void dumpButtonConditions(BitStream *); +#endif +}; + +#endif /* _BUTTON_H_ */ diff --git a/core/multimedia/opieplayer/libflash/character.cc b/core/multimedia/opieplayer/libflash/character.cc new file mode 100644 index 0000000..4b5ce36 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/character.cc @@ -0,0 +1,233 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +///// Character member definitions + +Character::Character(ObjectType objectType, long tagid) +{ + type = objectType; + tagId = tagid; + name = NULL; +} + +Character::~Character() +{ + delete name; +} + +int +Character::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform) +{ + printf("Cannot be executed\n"); + return 0; +} + +ActionRecord * +Character::eventHandler(GraphicDevice *gd, FlashEvent *ev) +{ + fprintf(stderr,"Unable to handle event !!!\n"); + return 0; +} + +int +Character::isButton() +{ + return 0; +} + +int +Character::isSprite(void) +{ + return 0; +} + +char * +Character::getName() +{ + return name; +} + +void +Character::getBoundingBox(Rect *bb, DisplayListEntry *e) +{ + //fprintf(stderr,"Unable to handle getBoundingBox !!!\n"); + bb->xmin = LONG_MAX; + bb->ymin = LONG_MAX; + bb->ymax = LONG_MIN; + bb->ymax = LONG_MIN; + return; +} + +void +Character::getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func) +{ + fprintf(stderr,"Unable to handle getRegion !!!\n"); + return; +} + +long +Character::getTagId() +{ + return tagId; +} + +void +Character::reset() +{ +} + +ObjectType +Character::getType() +{ + return type; +} + +char * +Character::getTypeString() +{ + switch (type) { + case BitmapType: + return "Bitmap"; + case FontType: + return "Font"; + case ButtonType: + return "Button"; + case SpriteType: + return "Sprite"; + case ShapeType: + return "Shape"; + case SoundType: + return "Sound"; + case TextType: + return "Text"; + default: + return "Unknown"; + } +} + +void +Character::setName(char* string) +{ + name = strdup(string); +} + +///// Dict methods definitions + +Dict::Dict() +{ + head = 0; +} + +Dict::~Dict() +{ + struct sCharCell *cell,*del; + + for(cell = head; cell;) + { + del = cell; + cell = cell->next; + delete del->elt; + delete del; + } +} + +void +Dict::addCharacter(Character *character) +{ + struct sCharCell *cell; + + cell = new sCharCell; + if (cell == NULL) { + delete character; + return; + } + cell->elt = character; + cell->next = head; + + head = cell; +} + +Character * +Dict::getCharacter(long id) +{ + struct sCharCell *cell; + + for(cell = head; cell; cell = cell->next) + { + if (id == cell->elt->getTagId()) return cell->elt; + } + return 0; +} + +void +Dict::dictRewind() +{ + currentCell = head; +} + +Character * +Dict::dictNextCharacter() +{ + if (currentCell) { + struct sCharCell *cell; + + cell = currentCell; + currentCell = currentCell->next; + return cell->elt; + } else { + return 0; + } +} + +void +Dict::nameCharacter(long id, char *string) +{ + struct sCharCell *cell; + + for(cell = head; cell; cell = cell->next) + { + if (cell->elt->getTagId() == id) { + cell->elt->setName(string); + break; + } + } +} + +#ifdef DUMP +void +Dict::dictSetUnsaved() +{ + struct sCharCell *cell; + + for(cell = head; cell; cell = cell->next) + { + cell->elt->saved = 0; + } +} +#endif diff --git a/core/multimedia/opieplayer/libflash/character.h b/core/multimedia/opieplayer/libflash/character.h new file mode 100644 index 0000000..583cb17 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/character.h @@ -0,0 +1,90 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _CHARACTER_H_ +#define _CHARACTER_H_ + +enum ObjectType { + ShapeType, + TextType, + FontType, + SoundType, + BitmapType, + SpriteType, + ButtonType +}; + +class DisplayListEntry; + +// Character definition + +class Character { + long tagId; + ObjectType type; + char *name; + +public: + Character(ObjectType type, long tagId); + virtual ~Character(); + + virtual int execute(GraphicDevice *, Matrix *, Cxform *); // Display, play or whatever + virtual int isButton(void); // True if Character is a button + virtual int isSprite(void); + virtual ActionRecord *eventHandler(GraphicDevice *, FlashEvent *); + virtual void getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func); + virtual void reset(); // Reset internal state of object + virtual void getBoundingBox(Rect *bb, DisplayListEntry *de); +#ifdef DUMP + virtual void dump(BitStream *main); + + int saved; +#endif + + long getTagId(); // Return tagId + ObjectType getType(); + char *getTypeString(); + char *getName(); + void setName(char *); +}; + +struct sCharCell { + Character *elt; + struct sCharCell *next; +}; + +class Dict { + struct sCharCell *head; + struct sCharCell *currentCell; // Iteration variable for dictNextCharacter + +public: + Dict(); + ~Dict(); + + void addCharacter(Character *character); + void nameCharacter(long id, char *string); + Character *getCharacter(long id); + void dictRewind(); + Character *dictNextCharacter(); + +#ifdef DUMP + void dictSetUnsaved(); +#endif +}; + +#endif /* _CHARACTER_H_ */ diff --git a/core/multimedia/opieplayer/libflash/cxform.cc b/core/multimedia/opieplayer/libflash/cxform.cc new file mode 100644 index 0000000..b448f5d --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/cxform.cc @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id"; +#endif + +long +Cxform::getRed(long v) { + long val; + + val = (long)(ra*v+rb); + if (val > 255) val = 255; + else if (val < 0) val = 0; + return val; +} + +long +Cxform::getGreen(long v) { + long val; + + val = (long)(ga*v+gb); + if (val > 255) val = 255; + else if (val < 0) val = 0; + return val; +} + +long +Cxform::getBlue(long v) { + long val; + + val = (long)(ba*v+bb); + if (val > 255) val = 255; + else if (val < 0) val = 0; + return val; +} + +long +Cxform::getAlpha(long v) { + long val; + + val = (long)(aa*v+ab); + if (val > 255) val = 255; + else if (val < 0) val = 0; + return val; +} + +Color +Cxform::getColor(Color color) { + Color newColor; + + newColor.red = getRed(color.red); + newColor.green = getGreen(color.green); + newColor.blue = getBlue(color.blue); + newColor.alpha = getAlpha(color.alpha); + + return newColor; +} diff --git a/core/multimedia/opieplayer/libflash/cxform.h b/core/multimedia/opieplayer/libflash/cxform.h new file mode 100644 index 0000000..14f7189 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/cxform.h @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _CXFORM_H_ +#define _CXFORM_H_ + +struct Color { + unsigned char red,green,blue,alpha; + long pixel; +}; + +struct Cxform +{ + float aa; long ab; // a is multiply factor, b is addition factor + float ra; long rb; + float ga; long gb; + float ba; long bb; + + long getRed(long v); + long getGreen(long v); + long getBlue(long v); + long getAlpha(long v); + Color getColor(Color color); + +#ifdef DUMP + void dump(BitStream *bs, int alpha = 0); +#endif +}; + +#endif /* _CXFORM_H_ */ diff --git a/core/multimedia/opieplayer/libflash/displaylist.cc b/core/multimedia/opieplayer/libflash/displaylist.cc new file mode 100644 index 0000000..d71cfb7 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/displaylist.cc @@ -0,0 +1,708 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +void deleteButton(FlashMovie *movie, DisplayListEntry *e) +{ + /* save the focus */ + if (movie->mouse_active == 0 && e->renderState == stateOver) { + movie->lost_over = (Button *)e->character; + movie->cur_focus = NULL; + } + + if (e == movie->cur_focus) { + movie->cur_focus = NULL; + } +} + +void addButton(FlashMovie *movie, DisplayListEntry *e) +{ + if (movie->mouse_active == 0 && + movie->cur_focus == NULL && + movie->lost_over == (Button *)e->character) { + /* restore the lost focus */ + e->renderState = stateOver; + e->oldState = stateOver; + ((Button *)e->character)->updateButtonState(e); + movie->lost_over = NULL; + movie->cur_focus = e; + } +} + +DisplayList::DisplayList(FlashMovie *movie) +{ + list = NULL; + this->movie = movie; + bbox.reset(); + isSprite = 0; +} + +DisplayList::~DisplayList() +{ + clearList(); +} + +void +DisplayList::clearList() +{ + DisplayListEntry *del, *e; + + for(e = list; e;) + { + updateBoundingBox(e); + if (e->character->isButton()) { + deleteButton(movie,e); + } + del = e; + e = e->next; + delete del; + } + list = 0; +} + +DisplayListEntry * +DisplayList::getList() +{ + return list; +} + +static void bbox(Rect *rect, Matrix *m, long x1, long y1) +{ + long x,y; + + x = m->getX(x1,y1); + y = m->getY(x1,y1); + if (x < rect->xmin) rect->xmin = x; + if (x > rect->xmax) rect->xmax = x; + if (y < rect->ymin) rect->ymin = y; + if (y > rect->ymax) rect->ymax = y; +} + +// Update bb to include boundary, optional reset of bb +void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset) +{ + if (reset) { + bb->reset(); + } + + if (boundary->xmin != LONG_MAX) { + bbox(bb, matrix, boundary->xmin, boundary->ymin); + bbox(bb, matrix, boundary->xmax, boundary->ymin); + bbox(bb, matrix, boundary->xmin, boundary->ymax); + bbox(bb, matrix, boundary->xmax, boundary->ymax); + } +} + +void +DisplayList::placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix, Cxform *cxform, char *name) +{ + DisplayListEntry *n,*e,*prev; + + n = new DisplayListEntry; + if (n == NULL) return; + + n->depth = depth; + n->matrix = matrix; + n->cxform = cxform; + n->character = character; + n->instanceName = name; + n->owner = this; + +#if 0 + printf("Dl %lx: placeObject: depth=%d character=%d cxform=%p\n", + this, n->depth,n->character ? n->character->getTagId() : 0, cxform); +#endif + + if (character == 0 || matrix == 0 || cxform == 0) { + for (e = list; e; prev = e, e = e->next) { + if (e->depth == n->depth) { + if (character == 0) { + n->character = e->character; + } + if (matrix == 0) { + n->matrix = e->matrix; + } + if (cxform == 0) { + n->cxform = e->cxform; + } + break; + } + } + } + + if (n->character == 0) { + // Not found !!! Should not happen + // printf("PlaceObject cannot find character at depth %ld\n", n->depth); + delete n; + return; + } + + prev = 0; + for (e = list; e; prev = e, e = e->next) + { + if (e->depth == n->depth) { + if (e->character->isButton()) { + deleteButton(movie, e); + } + + // Do update, object has moved or been resized + updateBoundingBox(e); + + // Replace object + e->depth = n->depth; + e->matrix = n->matrix; + e->cxform = n->cxform; + e->character = n->character; + /* if it is a button, we must update its state */ + if (e->character->isButton()) { + movie->buttons_updated = 1; + addButton(movie, e); + } + + updateBoundingBox(e); + + delete n; + return; + } + if (e->depth > n->depth) break; + } + /* new object */ + + /* button instantiation */ + if (n->character->isButton()) { + n->renderState = stateUp; + n->oldState = stateUp; + ((Button *)n->character)->updateButtonState(n); + addButton(movie,n); + } + + updateBoundingBox(n); + + if (prev == 0) { + // Object comes at first place + n->next = list; + list = n; + } else { + // Insert object + n->next = prev->next; + prev->next = n; + } +} + + +Character * +DisplayList::removeObject(GraphicDevice *gd,Character *character, long depth) +{ + DisplayListEntry *e,*prev; + + // List should not be empty + if (list == 0) return 0; + +#if 0 + printf("removeObject: depth=%d character=%d\n", + depth,character ? character->getTagId() : 0); +#endif + + prev = 0; + for (e = list; e; prev = e, e = e->next) { + if (e->depth == depth) { + if (prev) { + prev->next = e->next; + } else { + list = e->next; + } + if (character == 0) { + character = e->character; + } + if (e->character->isButton()) { + deleteButton(movie, e); + } + if (e->character->isSprite()) { + ((Sprite*)e->character)->reset(); + } + + updateBoundingBox(e); + + delete e; + return character; + } + } + return 0; // Should not happen +} + +void +DisplayList::updateBoundingBox(DisplayListEntry *e) +{ + Rect rect; + + //rect.reset(); + e->character->getBoundingBox(&rect,e); + transformBoundingBox(&this->bbox, e->matrix, &rect, 0); +} + +int +DisplayList::updateSprites() +{ + Sprite *sprite; + DisplayListEntry *e; + int refresh = 0; + + for (e = this->list; e != NULL; e = e->next) { + if (e->character->isButton() && e->buttonCharacter) { + if (e->buttonCharacter->isSprite()) { + Matrix mat; + + sprite = (Sprite *)e->buttonCharacter; + refresh |= sprite->program->dl->updateSprites(); + refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform); + mat = (*e->matrix) * e->buttonMatrix; + transformBoundingBox(&this->bbox, &mat, + &(sprite->program->dl->bbox), + 0); + } + } + if (e->character->isSprite()) { + sprite = (Sprite *)e->character; + refresh |= sprite->program->dl->updateSprites(); + refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform); + transformBoundingBox(&this->bbox, e->matrix, + &(sprite->program->dl->bbox), + 0); + } + } + return refresh; +} + +/* Function can return either 0,1 or 2 + 0: Nothing match, continue + 1: Something matches, but continue searching + 2: Something matches, but stop searching +*/ + +static int exploreButtons1(Program *prg, void *opaque, + ExploreButtonFunc func) +{ + DisplayListEntry *e; + int ret, ret2 = 0; + + for(e=prg->dl->list; e != NULL; e = e->next) { + if (e->character == NULL) continue; + if (e->character->isButton()) { + ret = func(opaque,prg,e); + if (ret == 2) return ret; // Func asks to return at once !!! + if (ret) ret2 = 1; + } + if (e->character->isSprite()) { + ret = exploreButtons1(((Sprite *)e->character)->program, + opaque,func); + if (ret == 2) return ret; // Func asks to return at once !!! + if (ret) ret2 = 1; + } + } + return ret2; +} + +int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func) +{ + CInputScript *script; + int ret; + + script = movie->main; + while (script != NULL) { + if (script->program) { + ret = exploreButtons1(script->program, opaque, func); + if (ret) return ret; + } + script = script->next; + } + return 0; +} + +typedef struct { + long x,y; + int hit; + DisplayListEntry *bhit; +} HitTable; + +static void button_hit_func(void *id, long y, long start, long end) +{ + HitTable *h = (HitTable *) id; + if ( y == h->y && (h->x >= start && h->x < end) ) + h->hit = 1; +} + +typedef struct { + FlashMovie *movie; + DisplayListEntry *bhit; +} ButtonHit; + +static int button_hit(void *opaque, Program *prg, DisplayListEntry *e) +{ + ButtonHit *h = (ButtonHit *) opaque; + HitTable hit_table; + FlashMovie *movie = h->movie; + Rect bb,boundary; + Matrix mat; + ButtonState save; + + hit_table.x = movie->mouse_x; + hit_table.y = movie->mouse_y / FRAC; + hit_table.hit = 0; + + // Compute the bounding box in screen coordinates + save = e->renderState; + e->renderState = stateHitTest; + e->character->getBoundingBox(&boundary,e); + e->renderState = save; + mat = (*movie->gd->adjust) * e->renderMatrix; + transformBoundingBox(&bb, &mat, &boundary, 1); + // Check if mouse is within bb + if (movie->mouse_x < bb.xmin) return 0; + if (movie->mouse_x > bb.xmax) return 0; + if (movie->mouse_y < bb.ymin) return 0; + if (movie->mouse_y > bb.ymax) return 0; + + e->character->getRegion(movie->gd, &e->renderMatrix, + &hit_table, button_hit_func); + + if (hit_table.hit) { + h->bhit = e; + return 1; + } else { + return 0; + } +} + +static int button_reset(void *opaque, Program *prg, DisplayListEntry *e) +{ + if (e->renderState != stateUp) { + e->owner->updateBoundingBox(e); + e->oldState = e->renderState; + e->renderState = stateUp; + ((Button *)e->character)->updateButtonState(e); + e->owner->updateBoundingBox(e); + } + return 0; +} + +/* update the button states according to the current mouse state & return the list of actions */ +void +DisplayList::updateButtons(FlashMovie *movie) +{ + DisplayListEntry *bhit; + ButtonHit h; + + if (movie->mouse_active) { + + h.bhit = NULL; + h.movie = movie; + + exploreButtons(movie, &h, button_hit); + + bhit = h.bhit; + + /* set every button to not hit */ + exploreButtons(movie, NULL, button_reset); + + if (bhit) { + ButtonState state; + + if (movie->button_pressed) { + state = stateDown; + } else { + state = stateOver; + } + if (state != bhit->renderState) { + bhit->owner->updateBoundingBox(bhit); + bhit->renderState = state; + ((Button *)bhit->character)->updateButtonState(bhit); + bhit->owner->updateBoundingBox(bhit); + movie->cur_focus = bhit; + if (movie->cursorOnOff) + movie->cursorOnOff(1,movie->cursorOnOffClientData); + } + } else { + if (movie->cursorOnOff) + movie->cursorOnOff(0,movie->cursorOnOffClientData); + } + } +} + +typedef struct { + ActionRecord *action; // Action to do + Program *prg; // Context program +} ButtonAction; + +static int button_action(void *opaque, Program *prg, DisplayListEntry *e) +{ + ButtonAction *h = (ButtonAction *)opaque; + static ActionRecord actionRefresh; + static ActionRecord soundFx; + Button *b; + ActionRecord **paction; + int n; + + actionRefresh.action = ActionRefresh; + actionRefresh.next = 0; + + soundFx.action = ActionPlaySound; + soundFx.next = &actionRefresh; + + b = (Button *)e->character; + + if (e->oldState != e->renderState) { + + paction = &actionRefresh.next; + + if (b->conditionList) { + *paction = b->getActionFromTransition(e->renderState, e->oldState); + } else if (e->renderState == stateDown) { + /* if the button is pressed and + no condition list is defined*/ + *paction = b->actionRecords; + } + + switch(e->renderState) { + case stateUp: + n = 0; + break; + case stateOver: + n = 1; + break; + default: + /* case stateDown: */ + n = 2; + break; + } + + if (b->sound[n]) { + soundFx.sound = b->sound[n]; + h->action = &soundFx; + } else { + h->action = &actionRefresh; + } + + e->oldState = e->renderState; + + h->prg = prg; + return 2; + } + h->action = 0; // Nothing to do about this + return 0; +} + +int computeActions(FlashMovie *movie, Program **prg, ActionRecord **ar) +{ + ButtonAction h; + + h.action = NULL; + exploreButtons(movie, &h, button_action); + if (h.action) { + *prg = h.prg; + *ar = h.action; + return 1; + } + return 0; +} + +#define FOCUS_ZOOM 1.5 +/* in pixels */ +#define FOCUS_SIZE_MIN 50 +#define FOCUS_TRANSLATE 15 + +int +DisplayList::render(GraphicDevice *gd, Matrix *render_matrix, Cxform *cxform) +{ + DisplayListEntry *e,*cur_focus; + int sprite = 0; + long n = 0; + Cxform cxf,*cxf1; + Rect bb,boundary; + + cur_focus = NULL; + + /* + if (isSprite == 0) { + if (this->bbox.xmin == LONG_MAX) return 0; + gd->updateClippingRegion(&this->bbox, render_matrix); + gd->clearCanvas(); + } + */ + + for (e = list; e; e = e->next) + { +#if PRINT + printf("Character %3d @ %3d\n", e->character ? e->character->getTagId() : 0, e->depth); +#endif + if (e->character) { + Matrix mat; + + if (render_matrix) { + mat = *render_matrix; + } + + if (e->matrix) { + mat = mat * (*e->matrix); + } + + /* fast clipping */ + // If object boundaries are outside current clip region give up with rendering + e->character->getBoundingBox(&boundary,e); + if (boundary.xmin != LONG_MAX) { + Matrix tmat; + + tmat = (*gd->adjust) * mat; + transformBoundingBox(&bb, &tmat, &boundary, 1); + + bb.xmin = bb.xmin >> FRAC_BITS; + bb.ymin = bb.ymin >> FRAC_BITS; + bb.xmax = (bb.xmax + FRAC - 1) >> FRAC_BITS; + bb.ymax = (bb.ymax + FRAC - 1) >> FRAC_BITS; + + if (bb.xmin >= gd->clip_rect.xmax || + bb.xmax <= gd->clip_rect.xmin || + bb.ymin >= gd->clip_rect.ymax || + bb.ymax <= gd->clip_rect.ymin) { + continue; + } + } + + if (cxform == NULL) { + cxf1 = e->cxform; + } + else if (e->cxform == NULL) { + cxf1 = cxform; + } + else { + cxf1 = &cxf; + cxf.ra = cxform->ra * e->cxform->ra; + cxf.ga = cxform->ga * e->cxform->ga; + cxf.ba = cxform->ba * e->cxform->ba; + cxf.aa = cxform->aa * e->cxform->aa; + + cxf.rb = (long)(cxform->ra * e->cxform->rb + cxform->rb); + cxf.gb = (long)(cxform->ga * e->cxform->gb + cxform->gb); + cxf.bb = (long)(cxform->ba * e->cxform->bb + cxform->bb); + cxf.ab = (long)(cxform->aa * e->cxform->ab + cxform->ab); + } + + if (e->character->isButton()) { + Button *b = (Button *) e->character; + + e->renderMatrix = mat; + + if (e->renderState != stateUp && movie->mouse_active == 0) { + cur_focus = e; + ((Button *)e->character)->updateButtonState(e); + } + + if (b->execute(gd, &mat, cxf1, e->renderState)) { + sprite = 1; + } + } else { + if (e->character->execute(gd, &mat, cxf1)) { + sprite = 1; + } + } + + n++; + } + } + +#if 0 + { + /* display the bounding box (debug) */ + Matrix tmat; + long x1,x2,y1,y2; + Color white; + + white.red = 255; + white.green = white.blue = 0; + gd->setForegroundColor(white); + + if (render_matrix) { + tmat = (*gd->adjust) * (*render_matrix); + } else { + tmat = *gd->adjust; + } + x1 = bbox.xmin; + y1 = bbox.ymin; + x2 = bbox.xmax; + y2 = bbox.ymax; + gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),10*FRAC); + gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),10*FRAC); + gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),10*FRAC); + gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),10*FRAC); + bbox.print(); + } +#endif + + // Reset clipping zone + bbox.reset(); + + return sprite; +} + +void +DisplayList::getBoundary(Rect *bb) +{ + DisplayListEntry *e; + Rect boundary; + + bb->reset(); + for (e = list; e; e = e->next) + { + if (e->character) { + e->character->getBoundingBox(&boundary,e); + transformBoundingBox(bb, e->matrix, &boundary, 0); + } + } +} + +extern "C" { + +void dump_buttons(FlashHandle flashHandle) +{ +#if 0 + Rect rect; + DisplayListEntry *e; + FlashMovie *movie; + + movie = (FlashMovie *)flashHandle; + + for (e = movie->first_button; e; e = e->next_button) { + computeBBox(movie,&rect,e); + printf("button: id=%d pos=%d %d %d %d\n", + e->character->getTagId(), + rect.xmin, rect.ymin, rect.xmax, rect.ymax); + } +#endif +} + +} diff --git a/core/multimedia/opieplayer/libflash/displaylist.h b/core/multimedia/opieplayer/libflash/displaylist.h new file mode 100644 index 0000000..536f628 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/displaylist.h @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _DISPLAYLIST_H_ +#define _DISPLAYLIST_H_ + +class Character; +class Program; + +struct DisplayList; + +// Display List management +struct DisplayListEntry { + Character *character; + long depth; + Matrix *matrix; + Cxform *cxform; + char *instanceName; + + /* button state */ + ButtonState renderState; + ButtonState oldState; + Character *buttonCharacter; + Matrix buttonMatrix; + Matrix renderMatrix; /* last render matrix */ + + DisplayListEntry *next; + + DisplayList *owner; // Parent +}; + +struct DisplayList { + DisplayListEntry *list; + FlashMovie *movie; + Rect bbox; // Delta clipping region + int isSprite; +public: + DisplayList(FlashMovie *movie); + ~DisplayList(); + DisplayListEntry *getList(); + void clearList(); + void placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix = 0, Cxform *cxform = 0, char *name = 0); + Character *removeObject(GraphicDevice *gd, Character *character, long depth); + + int render(GraphicDevice *gd, Matrix *m = 0, Cxform *cxform = 0); + void updateBoundingBox(DisplayListEntry *); + void updateButtons (FlashMovie *); + void getBoundary(Rect *bb); // Returns boundary of current displayed objects + int updateSprites(); // Update sprites in the display list +}; + +typedef void (*DisplayListFunc)(DisplayListEntry *e, void *opaque); + +void updateButtons(FlashMovie *m); +int computeActions(FlashMovie *m, Program **prog, ActionRecord **ar); +void renderFocus(FlashMovie *movie); + +typedef int (*ExploreButtonFunc)(void *opaque, Program *prg, DisplayListEntry *e); +int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func); +void updateBoundingBox(DisplayListEntry *e); +void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset); +void updateButtonState(DisplayListEntry *e, ButtonState state); + +#endif /* _DISPLAYLIST_H_ */ diff --git a/core/multimedia/opieplayer/libflash/flash.cc b/core/multimedia/opieplayer/libflash/flash.cc new file mode 100644 index 0000000..75d351c --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/flash.cc @@ -0,0 +1,275 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" +#include "graphic16.h" +#include "graphic24.h" +#include "graphic32.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +// Interface with standard C +extern "C" { + +FlashHandle +FlashNew() +{ + FlashMovie *fh; + + fh = new FlashMovie; + + fh->main = new CInputScript; + + return (FlashHandle)fh; +} + +int +FlashParse(FlashHandle flashHandle, int level, char *data, long size) +{ + FlashMovie *fh; + CInputScript *script; + int status = FLASH_PARSE_ERROR; + + fh = (FlashMovie *)flashHandle; + + for(script = fh->main; script != NULL; script = script->next) { + if (script->level == level) { + status = script->ParseData(fh, data, size); + + if (status & FLASH_PARSE_START) { + fh->msPerFrame = 1000/fh->main->frameRate; + script->program->rewindMovie(); + } + break; + } + } + + return status; +} + +void +FlashGetInfo(FlashHandle flashHandle, struct FlashInfo *fi) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fi->version = fh->main->m_fileVersion; + fi->frameRate = fh->main->frameRate; + fi->frameCount = fh->main->frameCount; + fi->frameWidth = fh->main->frameRect.xmax - fh->main->frameRect.xmin; + fi->frameHeight = fh->main->frameRect.ymax - fh->main->frameRect.ymin; +} + +long FlashGraphicInit(FlashHandle flashHandle, FlashDisplay *fd) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + switch (fd->bpp) { + case 4: + fh->gd = new GraphicDevice32(fd); + break; + case 3: + fh->gd = new GraphicDevice24(fd); + break; + case 2: + fh->gd = new GraphicDevice16(fd); + break; + default: + fprintf(stderr, "Unsupported depth\n"); + } + + fh->gd->setMovieDimension(fh->main->frameRect.xmax - fh->main->frameRect.xmin, + fh->main->frameRect.ymax - fh->main->frameRect.ymin); + + return 1; // Ok +} + +void +FlashSoundInit(FlashHandle flashHandle, char *device) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->sm = new SoundMixer(device); +} + +void +FlashZoom(FlashHandle flashHandle, int zoom) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->gd->setMovieZoom(zoom); +} + +void +FlashOffset(FlashHandle flashHandle, int x, int y) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->gd->setMovieOffset(x,y); +} + +long +FlashExec(FlashHandle flashHandle, long flag, + FlashEvent *fe, struct timeval *wakeDate) +{ + FlashMovie *fh; + long wakeUp = 0; + + fh = (FlashMovie *)flashHandle; + + if (fh->main == NULL) return 0; // Not ready + if (fh->main->program == NULL) return 0; // Not ready + if (fh->main->program->nbFrames == 0) return 0; // Still not ready + if (fh->gd == 0) return 0; + + switch (flag & FLASH_CMD_MASK) { + case FLASH_STOP: + fh->main->program->pauseMovie(); + wakeUp = 0; + break; + case FLASH_CONT: + fh->main->program->continueMovie(); + wakeUp = FLASH_STATUS_WAKEUP; + break; + case FLASH_REWIND: + fh->main->program->rewindMovie(); + wakeUp = 0; + break; + case FLASH_STEP: + fh->main->program->nextStepMovie(); + wakeUp = 0; + break; + } + + if (flag & FLASH_WAKEUP) { + // Compute next wakeup time + gettimeofday(wakeDate,0); + wakeDate->tv_usec += fh->msPerFrame*1000; + if (wakeDate->tv_usec > 1000000) { + wakeDate->tv_usec -= 1000000; + wakeDate->tv_sec++; + } + + // Play frame + wakeUp = fh->processMovie(fh->gd, fh->sm); + } + + if (checkFlashTimer(&fh->scheduledTime)) { + if (fh->handleEvent(fh->gd, fh->sm, &fh->scheduledEvent)) { + wakeUp = 1; + } + + setFlashTimer(&fh->scheduledTime, -1); + } + + if (flag & FLASH_EVENT) { + wakeUp = fh->handleEvent(fh->gd, fh->sm, fe); + if (wakeUp) { + /* Wake up at once, except for mouse move (40 ms after) */ + gettimeofday(wakeDate,0); + if (fe->type == FeMouseMove) { + wakeDate->tv_usec += 40*1000; + if (wakeDate->tv_usec > 1000000) { + wakeDate->tv_usec -= 1000000; + wakeDate->tv_sec++; + } + } + } + } + + return wakeUp || (fh->scheduledTime.tv_sec != -1); +} + +void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->getSwf = getSwf; + fh->getSwfClientData = clientData; +} + + +void +FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->cursorOnOff = cursorOnOff; + fh->cursorOnOffClientData = clientData; +} + +void +FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *clientData) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->getUrl = getUrl; + fh->getUrlClientData = clientData; +} + +void +FlashClose(FlashHandle flashHandle) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + delete fh; +} + +void +FlashSettings(FlashHandle flashHandle, long settings) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->main->program->modifySettings( settings ); +} + +int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb; + +void flash_dump(void) +{ + printf("flash: shape_size=%d (nb=%d)\n",shape_size,shape_nb); + printf("flash: shaperecord_size=%d (nb=%d)\n",shaperecord_size,shaperecord_nb); + printf("flash: style_size=%d (nb=%d)\n",style_size,style_nb); +} + +}; /* end of extern C */ diff --git a/core/multimedia/opieplayer/libflash/flash.h b/core/multimedia/opieplayer/libflash/flash.h new file mode 100644 index 0000000..9330713 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/flash.h @@ -0,0 +1,129 @@ +/*/////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +///////////////////////////////////////////////////////////// */ +#ifndef _FLASH_H_ +#define _FLASH_H_ + +#define PLUGIN_NAME "Shockwave Flash" +#define FLASH_VERSION_STRING "Version 0.4.10" + +/* Flags to pass to FlashExec */ +#define FLASH_WAKEUP 0x01 +#define FLASH_EVENT 0x02 +#define FLASH_CMD 0x04 + +/* Mask to extract commands */ +#define FLASH_CMD_MASK 0xf0 +/* Commands */ +#define FLASH_STOP 0x10 /* Pause the movie */ +#define FLASH_CONT 0x20 /* Continue the movie after pause */ +#define FLASH_REWIND 0x30 /* Rewind the movie and pause */ +#define FLASH_STEP 0x40 /* Frame by frame operation */ + +/* return codes of FlashExec */ +#define FLASH_STATUS_WAKEUP 0x01 /* FlashExec must be called again after a given time */ + +struct FlashInfo { + long frameRate; + long frameCount; + long frameWidth; + long frameHeight; + long version; +}; + +/* Player settings */ +#define PLAYER_LOOP (1<<0) +#define PLAYER_QUALITY (1<<1) +#define PLAYER_MENU (1<<2) + +/* Parser status */ +#define FLASH_PARSE_ERROR 0 +#define FLASH_PARSE_START 1 +#define FLASH_PARSE_NEED_DATA 2 +#define FLASH_PARSE_EOM 4 +#define FLASH_PARSE_WAKEUP 8 +#define FLASH_PARSE_OOM 16 /* Out Of Memory */ + +typedef void *FlashHandle; + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +enum FlashEventType { + FeNone, + FeMouseMove, + FeButtonPress, + FeButtonRelease, + FeRefresh, + FeKeyPress, + /* internal events */ + FeKeyRelease, +}; + +enum FlashKey { + FeKeyUp = 1, + FeKeyDown, + FeKeyLeft, + FeKeyRight, + FeKeyEnter, + FeKeyNext +}; + + + +typedef struct FlashEvent { + enum FlashEventType type; + int x,y; /* Mouse coordinates, + relative to upper-left window corner */ + enum FlashKey key; +} FlashEvent; + +typedef struct FlashDisplay { + void *pixels; + int bpl; /* bytes per line */ + int width; + int height; + int depth; + int bpp; + int flash_refresh; + /* Clipping region */ + int clip_x, clip_y; + int clip_width, clip_height; +} FlashDisplay; + +extern FlashHandle FlashNew(); +extern void FlashGetInfo(FlashHandle fh, struct FlashInfo *fi); +extern long FlashGraphicInit(FlashHandle fh, FlashDisplay *fd); +extern void FlashSoundInit(FlashHandle fh, char *device); +extern int FlashParse(FlashHandle fh, int level, char *data, long size); +extern long FlashExec(FlashHandle fh, long flag, FlashEvent *fe, struct timeval *wakeDate); +extern void FlashClose(FlashHandle fh); +extern void FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *); +extern void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData); +extern void FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData); +extern void FlashZoom(FlashHandle fh, int zoom); +extern void FlashOffset(FlashHandle fh, int x, int y); +extern void FlashSettings(FlashHandle fh, long settings); + +#if defined(__cplusplus) || defined(c_plusplus) +}; +#endif + +#endif /* _FLASH_H_ */ diff --git a/core/multimedia/opieplayer/libflash/font.cc b/core/multimedia/opieplayer/libflash/font.cc new file mode 100644 index 0000000..d937276 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/font.cc @@ -0,0 +1,105 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +SwfFont::SwfFont(long id) : Character(FontType, id) +{ + glyphs = 0; + nbGlyphs = 0; + name = NULL; + setFontName("Unknown"); + flags = (FontFlags)0; + lookUpTable = 0; +} + +SwfFont::~SwfFont() +{ + if (lookUpTable) { + delete lookUpTable; + } + delete name; + delete [] glyphs; +} + +void +SwfFont::setFontFlags(FontFlags f) +{ + flags = f; +} + +char * +SwfFont::getName() +{ + return name; +} + +FontFlags +SwfFont::getFlags() +{ + return flags; +} + +long +SwfFont::getNbGlyphs() +{ + return nbGlyphs; +} + +Shape * +SwfFont::getGlyph(long index) +{ + if (index >= nbGlyphs) return 0; + return &glyphs[index]; +} + +long +SwfFont::getGlyphCode(long index) +{ + if (lookUpTable == 0 || index >= nbGlyphs) return 0; + return lookUpTable[index]; +} + +void +SwfFont::setFontName(char *str) +{ + delete name; + name = new char[strlen(str)+1]; + strcpy(name,str); +} + +void +SwfFont::setFontLookUpTable(long *lut) +{ + lookUpTable = lut; +} + +void +SwfFont::setFontShapeTable(Shape *shapes, long n) +{ + glyphs = shapes; + nbGlyphs = n; +} diff --git a/core/multimedia/opieplayer/libflash/font.h b/core/multimedia/opieplayer/libflash/font.h new file mode 100644 index 0000000..bc151ca --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/font.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _SWFFONT_H_ +#define _SWFFONT_H_ + +class SwfFont : public Character { + Shape *glyphs; // Array + long nbGlyphs; + char *name; + FontFlags flags; + long *lookUpTable; // Array + + // Font2 + long ascent; + long descent; + long leading; + +public: + SwfFont(long id); + ~SwfFont(); + + void setFontShapeTable(Shape *shapes, long n); + void setFontName(char *str); + void setFontLookUpTable(long *lut); + void setFontFlags(FontFlags f); + long getGlyphCode(long index); + long getNbGlyphs(); + Shape *getGlyph(long index); + + char *getName(); + FontFlags getFlags(); + +#ifdef DUMP + void dump(BitStream *bs); + void dumpFontInfo(BitStream *bs); +#endif +}; + +#endif /* _SWFFONT_H_ */ diff --git a/core/multimedia/opieplayer/libflash/graphic.cc b/core/multimedia/opieplayer/libflash/graphic.cc new file mode 100644 index 0000000..f65011e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic.cc @@ -0,0 +1,632 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +// Public + +GraphicDevice::GraphicDevice(FlashDisplay *fd) +{ + flashDisplay = fd; + + bgInitialized = 0; + + // Reset flash refresh flag + flashDisplay->flash_refresh = 0; + + /* 16 bits, RGB565 */ + redMask = 0xF800; + greenMask = 0x07E0; + blueMask = 0x001F; + + /* should be the actual window size */ + targetWidth = fd->width; + targetHeight = fd->height; + bpl = fd->bpl; + +#if PRINT + printf("Target Width = %d\n", targetWidth); + printf("Target Height = %d\n", targetHeight); +#endif + + zoom = FRAC; + movieWidth = targetWidth; + movieHeight = targetHeight; + + viewPort.xmin = 0; + viewPort.xmax = targetWidth-1; + viewPort.ymin = 0; + viewPort.ymax = targetHeight-1; + + canvasBuffer = (unsigned char *) fd->pixels; + + adjust = new Matrix; + foregroundColor.red = 0; + foregroundColor.green = 0; + foregroundColor.blue = 0; + foregroundColor.alpha = ALPHA_OPAQUE; + + backgroundColor.red = 0; + backgroundColor.green = 0; + backgroundColor.blue = 0; + backgroundColor.alpha = ALPHA_OPAQUE; + + showMore = 0; + + setClipping(0); // Reset + setClipping(1); + + /* polygon rasterizer : handle memory errors ! */ + + height = targetHeight; + segs = (Segment **)malloc(height * sizeof(Segment *)); + memset(segs, 0, height * sizeof(Segment *)); + ymin = height; + ymax = -1; + + seg_pool = (Segment *)malloc(NB_SEGMENT_MAX * sizeof(Segment)); + seg_pool_cur = seg_pool; +} + +GraphicDevice::~GraphicDevice() +{ + free(segs); + free(seg_pool); + + if (adjust) { + delete adjust; + } +} + +Color * +GraphicDevice::getColormap(Color *old, long n, Cxform *cxform) +{ + Color *newCmp; + + newCmp = new Color[n]; + if (newCmp == NULL) return NULL; + + if (cxform) { + for(long i = 0; i < n; i++) + { + newCmp[i] = cxform->getColor(old[i]); + newCmp[i].pixel = allocColor(newCmp[i]); + } + } else { + for(long i = 0; i < n; i++) + { + newCmp[i] = old[i]; + newCmp[i].pixel = allocColor(old[i]); + } + } + + return newCmp; +} + +long +GraphicDevice::getHeight() +{ + return targetHeight; +} + +long +GraphicDevice::getWidth() +{ + return targetWidth; +} + +Color +GraphicDevice::getForegroundColor() +{ + return foregroundColor; +} + +void +GraphicDevice::setForegroundColor(Color color) +{ + foregroundColor = color; +} + +Color +GraphicDevice::getBackgroundColor() +{ + return backgroundColor; +} + +int +GraphicDevice::setBackgroundColor(Color color) +{ + if (bgInitialized == 0) { + backgroundColor = color; + clearCanvas(); + bgInitialized = 1; + return 1; + } + return 0; +} + +void +GraphicDevice::setMovieDimension(long width, long height) +{ + float xAdjust, yAdjust; + + movieWidth = width; + movieHeight = height; + + xAdjust = (float)targetWidth*zoom/(float)width; + yAdjust = (float)targetHeight*zoom/(float)height; + + if (xAdjust < yAdjust) { + adjust->a = xAdjust; + adjust->d = xAdjust; + adjust->ty = ((targetHeight*zoom) - (long)(height * xAdjust))/2; + viewPort.ymin = adjust->ty/zoom; + viewPort.ymax = targetHeight-viewPort.ymin-1; + } else { + adjust->a = yAdjust; + adjust->d = yAdjust; + adjust->tx = ((targetWidth*zoom) - (long)(width * yAdjust))/2; + viewPort.xmin = adjust->tx/zoom; + viewPort.xmax = targetWidth-viewPort.xmin-1; + } + + if (viewPort.xmin < 0) viewPort.xmin = 0; + if (viewPort.ymin < 0) viewPort.ymin = 0; + if (viewPort.xmax >= targetWidth) viewPort.xmax = targetWidth-1; + if (viewPort.ymax >= targetHeight) viewPort.ymax = targetHeight-1; +} + +void +GraphicDevice::setMovieZoom(int z) +{ + z *= FRAC; + if (z <= 0 || z > 100) return; + zoom = z; + setMovieDimension(movieWidth,movieHeight); +} + +void +GraphicDevice::setMovieOffset(long x, long y) +{ + adjust->tx = -zoom*x; + adjust->ty = -zoom*y; +} + +long +GraphicDevice::clip(long &y, long &start, long &end) +{ + long xmin,xend; + + if (y < clip_rect.ymin || + y >= clip_rect.ymax) return 1; + if (end <= start) + return 1; + xmin = clip_rect.xmin * FRAC; + xend = clip_rect.xmax * FRAC; + + if (end <= xmin || start >= xend) return 1; + + if (start < xmin) start = xmin; + if (end > xend) end = xend; + + return 0; +} + +void +GraphicDevice::drawBox(long x1, long y1, long x2, long y2) +{ + int i; + + for(i=0;i= NB_SEGMENT_MAX ) + return NULL; + seg = seg_pool_cur++; + + return seg; +} + +/* add a segment to the current path */ +void +GraphicDevice::addSegment(long x1, long y1, long x2, long y2, + FillStyleDef *f0, + FillStyleDef *f1, + int aa) +{ + Segment *seg,**segs; + long dX, X, Y, ymin, ymax, tmp; + FillStyleDef *ff; + + if ( y1 == y2 ) { + return; + } + + if (y1 < y2) { + ymin = y1; + ymax = y2; + ff = f0; + f0 = f1; + f1 = ff; + } else { + ymin = y2; + ymax = y1; + tmp = x1; + x1 = x2; + x2 = tmp; + } + + if (ymax>>FRAC_BITS < clip_rect.ymin) { + return; + } + if (ymin>>FRAC_BITS > clip_rect.ymax) { + return; + } + + X = x1 << SEGFRAC; + dX = ((x2 - x1)< ymax) { + //printf("Elimine @ y = %d ymin = %d, ymax = %d\n", Y, ymin, seg->ymax); + return; + } + X += dX * (Y-ymin); + + Y >>= FRAC_BITS; + if (Y >= clip_rect.ymax) { + return; + } + + seg = allocSeg(); + if (seg == NULL) { + return; + } + + seg->next = 0; + seg->nextValid = 0; + seg->aa = aa; + seg->ymax = ymax; + seg->x1 = x1; + seg->x2 = x2; + seg->X = X; + seg->dX = dX; + seg->fs[0] = f0; + seg->fs[1] = f1; + + if (Y < this->ymin) this->ymin = Y; + ymax = (seg->ymax + FRAC - 1) >> FRAC_BITS; + if (ymax >= this->height) ymax = this->height-1; + if (ymax > this->ymax) this->ymax = ymax; + + segs = this->segs; + + if (segs[Y] == 0) { + segs[Y] = seg; + } else { + Segment *s,*prev; + + prev = 0; + for(s = segs[Y]; s; prev = s, s = s->next) { + if (s->X > seg->X) { + if (prev) { + prev->next = seg; + seg->next = s; + } else { + seg->next = segs[Y]; + segs[Y] = seg; + } + break; + } + } + if (s == 0) { + prev->next = seg; + seg->next = s; + } + } +} + +inline Segment * +GraphicDevice::progressSegments(Segment * curSegs, long y) +{ + Segment *seg,*prev; + + // Update current segments + seg = curSegs; + prev = 0; + while(seg) + { + if ((y*FRAC) > seg->ymax) { + // Remove this segment, no more valid + if (prev) { + prev->nextValid = seg->nextValid; + } else { + curSegs = seg->nextValid; + } + seg = seg->nextValid; + } else { + seg->X += seg->dX * FRAC; + prev = seg; + seg = seg->nextValid; + } + } + return curSegs; +} + +inline Segment * +GraphicDevice::newSegments(Segment *curSegs, Segment *newSegs) +{ + Segment *s,*seg,*prev; + + s = curSegs; + prev = 0; + + // Check for new segments + for (seg = newSegs; seg; seg=seg->next) + { + // Place it at the correct position according to X + if (curSegs == 0) { + curSegs = seg; + seg->nextValid = 0; + } else { + for(; s; prev = s, s = s->nextValid) + { + if ( s->X > seg->X || + ( (s->X == seg->X) && + ( (seg->x1 == s->x1 && seg->dX < s->dX) || + (seg->x2 == s->x2 && seg->dX > s->dX) + ))) { + // Insert before s + if (prev) { + seg->nextValid = s; + prev->nextValid = seg; + } else { + seg->nextValid = curSegs; + curSegs = seg; + } + break; + } + } + // Append at the end + if (s == 0) { + prev->nextValid = seg; + seg->nextValid = 0; + } + } + + s = seg; + } + + return curSegs; +} + +#if 0 +static void +printSeg(Segment *seg) +{ + /* + printf("Seg %08x : X = %5d, Ft = %d, Cl = %2x/%2x/%2x, Cr = %2x/%2x/%2x, x1=%5d, x2=%5d, ymin=%5d, ymax=%5d\n", seg, + seg->X>>SEGFRAC, + seg->right ? seg->right->type: -1, + seg->left ? seg->left->color.red : -1, + seg->left ? seg->left->color.green : -1, + seg->left ? seg->left->color.blue : -1, + seg->right ? seg->right->color.red : -1, + seg->right ? seg->right->color.green : -1, + seg->right ? seg->right->color.blue : -1, + seg->x1, seg->x2, seg->ymin, seg->ymax); + */ +} +#endif + +inline void +GraphicDevice::renderScanLine(long y, Segment *curSegs) +{ + Segment *seg; + long width; + int fi = 1; + FillStyleDef *f; + + width = targetWidth * FRAC; + + if (curSegs && curSegs->fs[0] && curSegs->fs[1] == 0) { + fi = 0; + } + for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid) + { + if (seg->nextValid->X <0) continue; + if ((seg->X>>SEGFRAC) > width) break; + f = seg->fs[fi]; + if (f) { + switch (f->type) { + case f_Solid: + if (seg->aa) { + fillLineAA(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + } else { + fillLine(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + } + break; + case f_TiledBitmap: + case f_clippedBitmap: + fillLineBitmap(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + break; + case f_LinearGradient: + fillLineLG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + break; + case f_RadialGradient: + fillLineRG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + break; + case f_None: + break; + } + } + } +} + +/* draw the current path */ +void +GraphicDevice::drawPolygon(void) +{ + long y; + Segment *curSegs,*seg; + + // no segments ? + if (this->ymax == -1) + return; + + // Foreach scanline + curSegs = 0; + for(y=this->ymin; y <= this->ymax; y++) { + + // Make X values progess and remove unuseful segments + curSegs = progressSegments(curSegs, y); + + // Add the new segment starting at the y position. + curSegs = newSegments(curSegs, this->segs[y]); + + // Render the scanline + if (this->scan_line_func == NULL) { + renderScanLine(y, curSegs); + } else { + for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid) { + if (seg->nextValid->X >= seg->X) { + scan_line_func(this->scan_line_func_id, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + } + } + } + } + + /* free the segments */ + memset(this->segs + this->ymin, 0, + (this->ymax - this->ymin + 1) * sizeof(Segment *)); + + this->ymax = -1; + this->ymin = this->height; + + this->seg_pool_cur = this->seg_pool; +} + +void +GraphicDevice::updateClippingRegion(Rect *rect) +{ + if (!clipping) return; + + transformBoundingBox(&clip_rect, adjust, rect, 1); + clip_rect.xmin >>= FRAC_BITS; + clip_rect.xmax >>= FRAC_BITS; + clip_rect.ymin >>= FRAC_BITS; + clip_rect.ymax >>= FRAC_BITS; + + clip_rect.xmin-=2; + clip_rect.ymin-=2; + clip_rect.xmax+=2; + clip_rect.ymax+=2; + + if (clip_rect.xmin < viewPort.xmin) clip_rect.xmin = viewPort.xmin; + if (clip_rect.xmax < viewPort.xmin) clip_rect.xmax = viewPort.xmin; + if (clip_rect.ymin < viewPort.ymin) clip_rect.ymin = viewPort.ymin; + if (clip_rect.ymax < viewPort.ymin) clip_rect.ymax = viewPort.ymin; + + if (clip_rect.xmax > viewPort.xmax) clip_rect.xmax = viewPort.xmax; + if (clip_rect.ymax > viewPort.ymax) clip_rect.ymax = viewPort.ymax; + if (clip_rect.xmin > viewPort.xmax) clip_rect.xmin = viewPort.xmax; + if (clip_rect.ymin > viewPort.ymax) clip_rect.ymin = viewPort.ymax; +} + +void +GraphicDevice::setClipping(int value) +{ + clipping = value; + if (clipping == 0) { + // Reset region + clip_rect.xmin = viewPort.xmin; + clip_rect.xmax = viewPort.xmax; + clip_rect.ymin = viewPort.ymin; + clip_rect.ymax = viewPort.ymax; + } +} + +// Virtual +void +GraphicDevice::clearCanvas() +{ +} + +long +GraphicDevice::allocColor(Color color) +{ + return 0; +} + +void +GraphicDevice::fillLineBitmap(FillStyleDef *f, long y, long start, long end) +{ +} + +void +GraphicDevice::fillLineLG(Gradient *grad, long y, long start, long end) +{ +} + +void +GraphicDevice::fillLineRG(Gradient *grad, long y, long start, long end) +{ +} + +void +GraphicDevice::fillLine(FillStyleDef *f, long y, long start, long end) +{ +} + +void +GraphicDevice::fillLineAA(FillStyleDef *f, long y, long start, long end) +{ +} + +void +GraphicDevice::drawLine(long x1, long y1, long x2, long y2, long width) +{ +} diff --git a/core/multimedia/opieplayer/libflash/graphic.h b/core/multimedia/opieplayer/libflash/graphic.h new file mode 100644 index 0000000..63ebd99 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic.h @@ -0,0 +1,174 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _GRAPHIC_H_ +#define _GRAPHIC_H_ + +#define ALPHA_OPAQUE 255 + +enum FillType { + f_Solid = 0x00, + f_LinearGradient = 0x10, + f_RadialGradient = 0x12, + f_TiledBitmap = 0x40, + f_clippedBitmap = 0x41, + f_None = 0x80 +}; + +struct Gradient { + int nbGradients; + unsigned char ratio[8]; + Color color[8]; + // For rendering + Color *ramp; + Matrix imat; + int has_alpha; +}; + + +struct FillStyleDef { + FillType type; // See enum FillType + + // Solid + Color color; + + // Gradient + Gradient gradient; + + // Bitmap + Bitmap *bitmap; + Matrix bitmap_matrix; + Color *cmap; + unsigned char *alpha_table; + + // Gradient or Bitmap + Matrix matrix; + + FillStyleDef() { + style_size += sizeof(FillStyleDef); + style_nb++; + } +}; + +struct Segment { + long x1,x2; + long ymax; + FillStyleDef *fs[2]; // 0 is left 1 is right + int aa; + long dX; + long X; + + struct Segment *next; + struct Segment *nextValid; +}; + +/* fractional bits (we don't use twips here... too expensive) */ +#define FRAC_BITS 5 +#define FRAC (1 << FRAC_BITS) +#define NB_SEGMENT_MAX (2048*4) +#define SEGFRAC 8 + +class GraphicDevice { + int targetWidth; + int targetHeight; + Rect viewPort; + int movieWidth; + int movieHeight; + int zoom; + unsigned long redMask; + unsigned long greenMask; + unsigned long blueMask; + int clipping; + +public: + FlashDisplay *flashDisplay; + int bgInitialized; + Color backgroundColor; + Color foregroundColor; + +public: + void *scan_line_func_id; + ScanLineFunc scan_line_func; + Rect clip_rect; + +private: + Segment **segs; + int ymin,ymax; + int height; + Segment *seg_pool; + Segment *seg_pool_cur; + + Segment * allocSeg(); + Segment * progressSegments(Segment * curSegs, long y); + Segment * newSegments(Segment *curSegs, Segment *newSegs); + void renderScanLine(long y, Segment *curSegs); + +protected: + long clip(long &y, long &start, long &end); + +public: + Matrix *adjust; // Matrix to fit window (shrink or expand) + + long showMore; // Used for debugging + + // For Direct Graphics + unsigned char *canvasBuffer; // A pointer to canvas'memory + long bpl; // Bytes per line + long bpp; // Bytes per pixel + long pad; // Scanline pad in byte + + GraphicDevice(FlashDisplay *fd); + virtual ~GraphicDevice(); + + int setBackgroundColor(Color); + void setForegroundColor(Color); + Color getBackgroundColor(); + Color getForegroundColor(); + void setMovieDimension(long width, long height); + void setMovieZoom(int zoom); + void setMovieOffset(long x, long y); + long getWidth(); + long getHeight(); + Color *getColormap(Color *old, long n, Cxform *cxform); + + void drawBox(long x1, long y1, long x2, long y2); + + void addSegment(long x1, long y1, long x2, long y2, + FillStyleDef *f0, + FillStyleDef *f1, + int aa); + + void drawPolygon(void); + + void updateClippingRegion(Rect *); + void setClipping(int); + + // Virtual functions + virtual void clearCanvas(); + virtual long allocColor(Color color); + virtual void fillLineBitmap(FillStyleDef *f, long y, long start, long end); + virtual void fillLineLG(Gradient *grad, long y, long start, long end); + virtual void fillLineRG(Gradient *grad, long y, long start, long end); + virtual void fillLine(FillStyleDef *f, long y, long start, long end); + virtual void fillLineAA(FillStyleDef *f, long y, long start, long end); + virtual void drawLine(long x1, long y1, long x2, long y2, long width); + +}; + +#endif /* _GRAPHIC_H_ */ diff --git a/core/multimedia/opieplayer/libflash/graphic16.cc b/core/multimedia/opieplayer/libflash/graphic16.cc new file mode 100644 index 0000000..24d0c20 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic16.cc @@ -0,0 +1,658 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#include "graphic16.h" + +extern unsigned char SQRT[]; + +#define FULL_AA + +#define PRINT 0 + +typedef unsigned short TYPE; + +GraphicDevice16::GraphicDevice16(FlashDisplay *fd) : GraphicDevice(fd) +{ +} + +long +GraphicDevice16::allocColor(Color color) +{ + return (color.red >> 3)<<11 | (color.green>>2)<<5 | (color.blue>>3); +} + +void +GraphicDevice16::clearCanvas() +{ + TYPE pixel; + TYPE *point,*p; + long h, w,n; + + if (!bgInitialized) return; + + pixel = allocColor(backgroundColor); + + point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin; + w = clip_rect.xmax - clip_rect.xmin; + h = clip_rect.ymax - clip_rect.ymin; + + while (h--) { + p = point; + n = w; + while (n--) { + *p++ = pixel; + } + + point = (TYPE *)((char *)point + bpl); + } + + flashDisplay->flash_refresh = 1; + flashDisplay->clip_x = clip_rect.xmin; + flashDisplay->clip_y = clip_rect.ymin; + flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin; + flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin; +} + +#define RED_MASK 0xF800 +#define GREEN_MASK 0x07E0 +#define BLUE_MASK 0x001F + +/* alpha = 0 : select c1, alpha = 255 select c2 */ +static inline unsigned long +mix_alpha(unsigned long c1, + unsigned long c2, int alpha) +{ + long r1,r2,r; + long g1,g2,g; + long b1,b2,b; + + r1 = c1 & RED_MASK; + r2 = c2 & RED_MASK; + r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK; + + g1 = c1 & GREEN_MASK; + g2 = c2 & GREEN_MASK; + g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK; + + b1 = c1 & BLUE_MASK; + b2 = c2 & BLUE_MASK; + b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK; + + return (r|g|b); +} + +void +GraphicDevice16::fillLineAA(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line; + TYPE *point,pixel; + unsigned int alpha, start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + line = (TYPE *)(canvasBuffer + bpl*y); + + alpha = f->color.alpha; + pixel = f->color.pixel; + + if (alpha == ALPHA_OPAQUE) { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start]; + + if (start == end) { + *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255); + } else { + n = end-start; + if (start_alpha < 255) { + *point = mix_alpha(*point, pixel, start_alpha); + point++; + n--; + } + while (n > 0) { + *point = pixel; + point++; + n--; + } + if (end_alpha > 0) { + *point = mix_alpha(*point, pixel, end_alpha); + } + } + } else { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start]; + + if (start == end) { + *point = mix_alpha(*point, pixel, + ((start_alpha + end_alpha - 255) * alpha) >> 8); + } else { + n = end-start; + if (start_alpha < 255) { + *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8); + point++; + n--; + } + while (n > 0) { + *point = mix_alpha(*point, pixel, alpha); + point++; + n--; + } + if (end_alpha > 0) { + *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8); + } + } + } +} + +void +GraphicDevice16::fillLine(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line,*point; + TYPE pixel; + unsigned int alpha; + + if (clip(y,start,end)) return; + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + n = end-start; + pixel = f->color.pixel; + alpha = f->color.alpha; + if (alpha == ALPHA_OPAQUE) { + while (n--) { + *point = pixel; + point++; + } + } else { + while (n--) { + *point = mix_alpha(*point, pixel, alpha); + point++; + } + } +} + +void +GraphicDevice16::fillLineBitmap(FillStyleDef *f, long y, long start, long end) +{ + int n; + long x1,y1,dx,dy; + Matrix *m = &f->bitmap_matrix; + Bitmap *b = f->bitmap; + unsigned char *pixels; + TYPE *p; + Color *cmap; + long pixbpl; + TYPE pixel; + int offset; + unsigned char *alpha_table; + + /* safety test) */ + if (!b) return; + + if (clip(y,start,end)) return; + + start /= FRAC; + end /= FRAC; + n = end - start; + p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * 2); + + /* the coordinates in the image are normalized to 16 bits */ + x1 = (long) (m->a * start + m->b * y + m->tx); + y1 = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + pixels = b->pixels; + pixbpl = b->bpl; + cmap = f->cmap; + + if (b->alpha_buf == NULL) { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel; + *p = pixel; + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } else if (f->alpha_table) { + alpha_table = f->alpha_table; + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + pixel = cmap[pixels[offset]].pixel; + *p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]); + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } else { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + pixel = cmap[pixels[offset]].pixel; + *p = mix_alpha(*p, pixel, b->alpha_buf[offset]); + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } +} + +void +GraphicDevice16::fillLineLG(Gradient *grad, long y, long start, long end) +{ + long dr,r,v,r2; + register long n; + TYPE *line; + TYPE *point; + Color *cp,*ramp; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + r = (long) (m->a * start + m->b * y + m->tx); + dr = (long) (m->a); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + + r2 = r + n * dr; + if ( ((r | r2) & ~255) == 0 ) { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha); + point++; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + *point = (TYPE)ramp[v].pixel; + point++; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + cp = &ramp[v]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + r += dr; + } + } + } else { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha); + point++; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = (TYPE)ramp[v].pixel; + point++; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + cp = &ramp[v]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + r += dr; + } + } + } +} + +void +GraphicDevice16::fillLineRG(Gradient *grad, long y, long start, long end) +{ + long X,dx,r,Y,dy; + long dist2; + register long n; + Color *cp,*ramp; + TYPE *line; + TYPE *point; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + X = (long) (m->a * start + m->b * y + m->tx); + Y = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start == end) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r = SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255); + } else { + if (start_alpha < 255) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r = SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha); + point++; + X += dx; + Y += dy; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point = (TYPE)ramp[r].pixel; + point++; + X += dx; + Y += dy; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha); + } + } +#endif /* FULL_AA */ + + } else { + while (n--) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + cp = &ramp[r]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + X += dx; + Y += dy; + } + } +} + +void +GraphicDevice16::drawLine(long x1, long y1, long x2, long y2, long width) +{ + int n,adr,dx,dy,sx,color; + register int a; + register TYPE *pp; + int alpha; + + x1 = (x1) >> FRAC_BITS; + y1 = (y1) >> FRAC_BITS; + x2 = (x2) >> FRAC_BITS; + y2 = (y2) >> FRAC_BITS; + + if (y1 > y2 || (y1 == y2 && x1 > x2)) { + long tmp; + + tmp=x1; + x1=x2; + x2=tmp; + + tmp=y1; + y1=y2; + y2=tmp; + } + + if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return; + if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return; + if (x1 == x2 && y1 == y2) return; // Bad !!! + + if (y1 < clip_rect.ymin && y1 != y2) { + x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1); + y1 = clip_rect.ymin; + } + + if (y2 > clip_rect.ymax && y1 != y2) { + x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1); + y2 = clip_rect.ymax; + } + + if (x1 < x2) { + if (x1 < clip_rect.xmin && x1 != x2) { + y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1); + x1 = clip_rect.xmin; + } + + if (x2 > clip_rect.xmax && x1 != x2) { + y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1); + x2 = clip_rect.xmax; + } + } + + if (x1 > x2) { + if (x2 < clip_rect.xmin && x2 != x1) { + y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2); + x2 = clip_rect.xmin; + } + + if (x1 > clip_rect.xmax && x2 != x1) { + y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2); + x1 = clip_rect.xmax; + } + } + + // Check again + if (x1 == x2 && y1 == y2) return; + if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return; + if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return; + if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return; + if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return; + + sx=bpl >> 1; + adr=(y1 * sx + x1); + pp = (TYPE *)canvasBuffer + adr; + + dx = x2 - x1; + dy = y2 - y1; + + color = allocColor(foregroundColor); + alpha = foregroundColor.alpha; + + if (alpha == ALPHA_OPAQUE) { + +#define PUTPIXEL() \ + { \ + *pp=color; \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } else { +#define PUTPIXEL() \ + { \ + *pp=mix_alpha(*pp,color,alpha); \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } +} diff --git a/core/multimedia/opieplayer/libflash/graphic16.h b/core/multimedia/opieplayer/libflash/graphic16.h new file mode 100644 index 0000000..938d856 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic16.h @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +class GraphicDevice16: public GraphicDevice { +private: + long GraphicDevice16::allocColor(Color color); + +public: + GraphicDevice16(FlashDisplay *fd); + + void clearCanvas(); + void fillLineAA(FillStyleDef *f, long y, long start, long end); + void fillLine(FillStyleDef *f, long y, long start, long end); + void fillLineBitmap(FillStyleDef *f, long y, long start, long end); + void fillLineLG(Gradient *grad, long y, long start, long end); + void fillLineRG(Gradient *grad, long y, long start, long end); + void drawLine(long x1, long y1, long x2, long y2, long width); +}; diff --git a/core/multimedia/opieplayer/libflash/graphic24.cc b/core/multimedia/opieplayer/libflash/graphic24.cc new file mode 100644 index 0000000..6d15019 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic24.cc @@ -0,0 +1,648 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#include "graphic24.h" + +extern unsigned char SQRT[]; + +#define FULL_AA + +#define PRINT 0 + +typedef unsigned char TYPE; +#define BPP 3 + +GraphicDevice24::GraphicDevice24(FlashDisplay *fd) : GraphicDevice(fd) +{ +} + +long +GraphicDevice24::allocColor(Color color) +{ + return 0; +} + +void +GraphicDevice24::clearCanvas() +{ + TYPE *point,*p; + long h, w,n; + + if (!bgInitialized) return; + + point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin*BPP; + w = clip_rect.xmax - clip_rect.xmin; + h = clip_rect.ymax - clip_rect.ymin; + + while (h--) { + p = point; + n = w; + while (n--) { + *p++ = backgroundColor.blue; + *p++ = backgroundColor.green; + *p++ = backgroundColor.red; + } + + point = (TYPE *)((char *)point + bpl); + } + + flashDisplay->flash_refresh = 1; + flashDisplay->clip_x = clip_rect.xmin; + flashDisplay->clip_y = clip_rect.ymin; + flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin; + flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin; +} + +/* alpha = 0 : select c1, alpha = 255 select c2 */ +static inline void mix_alpha(TYPE *c1, Color c2, int alpha) +{ + *c1 = (((c2.blue- (*c1))*alpha + (*c1) * 256) >> 8); + c1++; + *c1 = (((c2.green- (*c1))*alpha + (*c1) * 256) >> 8); + c1++; + *c1 = (((c2.red- (*c1))*alpha + (*c1) * 256) >> 8); +} + +void +GraphicDevice24::fillLineAA(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line; + TYPE *point; + Color pixel; + unsigned int alpha, start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + line = (TYPE *)(canvasBuffer + bpl*y); + + alpha = f->color.alpha; + pixel = f->color; + + if (alpha == ALPHA_OPAQUE) { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start*BPP]; + + if (start == end) { + mix_alpha(point, pixel, start_alpha + end_alpha - 255); + } else { + n = end-start; + if (start_alpha < 255) { + mix_alpha(point, pixel, start_alpha); + point += BPP; + n--; + } + while (n > 0) { + *point++ = pixel.blue; + *point++ = pixel.green; + *point++ = pixel.red; + n--; + } + if (end_alpha > 0) { + mix_alpha(point, pixel, end_alpha); + } + } + } else { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start*BPP]; + + if (start == end) { + mix_alpha(point, pixel, ((start_alpha + end_alpha - 255) * alpha) >> 8); + } else { + n = end-start; + if (start_alpha < 255) { + mix_alpha(point, pixel, (start_alpha * alpha) >> 8); + point+=BPP; + n--; + } + while (n > 0) { + mix_alpha(point, pixel, alpha); + point+=BPP; + n--; + } + if (end_alpha > 0) { + mix_alpha(point, pixel, (end_alpha * alpha) >> 8); + } + } + } +} + +void +GraphicDevice24::fillLine(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line,*point; + Color pixel; + unsigned int alpha; + + if (clip(y,start,end)) return; + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start*BPP]; + n = end-start; + alpha = f->color.alpha; + pixel = f->color; + if (alpha == ALPHA_OPAQUE) { + while (n--) { + *point++ = pixel.blue; + *point++ = pixel.green; + *point++ = pixel.red; + } + } else { + while (n--) { + mix_alpha(point, pixel, alpha); + point+=BPP; + } + } +} + +void +GraphicDevice24::fillLineBitmap(FillStyleDef *f, long y, long start, long end) +{ + int n; + long x1,y1,dx,dy; + Matrix *m = &f->bitmap_matrix; + Bitmap *b = f->bitmap; + unsigned char *pixels; + TYPE *p; + Color *cmap; + long pixbpl; + Color pixel; + int offset; + unsigned char *alpha_table; + + /* safety test) */ + if (!b) return; + + if (clip(y,start,end)) return; + + start /= FRAC; + end /= FRAC; + n = end - start; + p = (TYPE *) (canvasBuffer + bpl*y + start*BPP); + + x1 = (long) (m->a * start + m->b * y + m->tx); + y1 = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + pixels = b->pixels; + pixbpl = b->bpl; + cmap = f->cmap; + + if (b->alpha_buf == NULL) { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]]; + *p++ = pixel.blue; + *p++ = pixel.green; + *p++ = pixel.red; + } else { + p+=BPP; + } + x1 += dx; + y1 += dy; + n--; + } + } else if (f->alpha_table) { + alpha_table = f->alpha_table; + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + mix_alpha(p, cmap[pixels[offset]], alpha_table[b->alpha_buf[offset]]); + } + p+=BPP; + x1 += dx; + y1 += dy; + n--; + } + } else { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + mix_alpha(p, cmap[pixels[offset]], b->alpha_buf[offset]); + } + p+=BPP; + x1 += dx; + y1 += dy; + n--; + } + } +} + +void +GraphicDevice24::fillLineLG(Gradient *grad, long y, long start, long end) +{ + long dr,r,v,r2; + register long n; + TYPE *line; + TYPE *point; + Color *cp,*ramp; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + r = (long) (m->a * start + m->b * y + m->tx); + dr = (long) (m->a); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start*BPP]; + + r2 = r + n * dr; + if ( ((r | r2) & ~255) == 0 ) { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + mix_alpha(point, ramp[v], start_alpha); + point+=BPP; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + *point++ = ramp[v].blue; + *point++ = ramp[v].green; + *point++ = ramp[v].red; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + mix_alpha(point, ramp[v], end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + cp = &ramp[v]; + mix_alpha(point, *cp, cp->alpha); + point+=BPP; + r += dr; + } + } + } else { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + mix_alpha(point, ramp[v], start_alpha); + point+=BPP; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point++ = ramp[v].blue; + *point++ = ramp[v].green; + *point++ = ramp[v].red; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + mix_alpha(point, ramp[v], end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + cp = &ramp[v]; + mix_alpha(point, *cp, cp->alpha); + point+=BPP; + r += dr; + } + } + } +} + +void +GraphicDevice24::fillLineRG(Gradient *grad, long y, long start, long end) +{ + long X,dx,r,Y,dy; + long dist2; + register long n; + Color *cp,*ramp; + TYPE *line; + TYPE *point; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + X = (long) (m->a * start + m->b * y + m->tx); + Y = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start*BPP]; + + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start == end) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + mix_alpha(point, ramp[r], start_alpha + end_alpha - 255); + } else { + if (start_alpha < 255) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + mix_alpha(point, ramp[r], start_alpha); + point+=BPP; + X += dx; + Y += dy; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point++ = ramp[r].blue; + *point++ = ramp[r].green; + *point++ = ramp[r].red; + X += dx; + Y += dy; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + mix_alpha(point, ramp[r], end_alpha); + } + } +#endif /* FULL_AA */ + + } else { + while (n--) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + cp = &ramp[r]; + mix_alpha(point, *cp, cp->alpha); + point+=BPP; + X += dx; + Y += dy; + } + } +} + +void +GraphicDevice24::drawLine(long x1, long y1, long x2, long y2, long width) +{ + int n,adr,dx,dy,sx; + Color color; + register int a; + register TYPE *pp; + int alpha; + + x1 = (x1) >> FRAC_BITS; + y1 = (y1) >> FRAC_BITS; + x2 = (x2) >> FRAC_BITS; + y2 = (y2) >> FRAC_BITS; + + if (y1 > y2 || (y1 == y2 && x1 > x2)) { + long tmp; + + tmp=x1; + x1=x2; + x2=tmp; + + tmp=y1; + y1=y2; + y2=tmp; + } + + if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return; + if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return; + if (x1 == x2 && y1 == y2) return; // Bad !!! + + if (y1 < clip_rect.ymin && y1 != y2) { + x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1); + y1 = clip_rect.ymin; + } + + if (y2 > clip_rect.ymax && y1 != y2) { + x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1); + y2 = clip_rect.ymax; + } + + if (x1 < x2) { + if (x1 < clip_rect.xmin && x1 != x2) { + y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1); + x1 = clip_rect.xmin; + } + + if (x2 > clip_rect.xmax && x1 != x2) { + y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1); + x2 = clip_rect.xmax; + } + } + + if (x1 > x2) { + if (x2 < clip_rect.xmin && x2 != x1) { + y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2); + x2 = clip_rect.xmin; + } + + if (x1 > clip_rect.xmax && x2 != x1) { + y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2); + x1 = clip_rect.xmax; + } + } + + // Check again + if (x1 == x2 && y1 == y2) return; + if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return; + if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return; + if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return; + if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return; + + sx=bpl >> 1; + adr=(y1 * sx + x1); + pp = (TYPE *)canvasBuffer + adr; + + dx = x2 - x1; + dy = y2 - y1; + + color = foregroundColor; + alpha = foregroundColor.alpha; + + if (alpha == ALPHA_OPAQUE) { + +#define PUTPIXEL() \ + { \ + *pp++=color.red; \ + *pp++=color.green; \ + *pp++=color.blue; \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } else { +#define PUTPIXEL() \ + { \ + mix_alpha(pp,color,alpha); \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1*BPP); a-=dx; }\ + else { pp+=(inc_2*BPP); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } +} diff --git a/core/multimedia/opieplayer/libflash/graphic24.h b/core/multimedia/opieplayer/libflash/graphic24.h new file mode 100644 index 0000000..4c10e49 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic24.h @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +class GraphicDevice24: public GraphicDevice { +private: + long GraphicDevice24::allocColor(Color color); + +public: + GraphicDevice24(FlashDisplay *fd); + + void clearCanvas(); + void fillLineAA(FillStyleDef *f, long y, long start, long end); + void fillLine(FillStyleDef *f, long y, long start, long end); + void fillLineBitmap(FillStyleDef *f, long y, long start, long end); + void fillLineLG(Gradient *grad, long y, long start, long end); + void fillLineRG(Gradient *grad, long y, long start, long end); + void drawLine(long x1, long y1, long x2, long y2, long width); +}; diff --git a/core/multimedia/opieplayer/libflash/graphic32.cc b/core/multimedia/opieplayer/libflash/graphic32.cc new file mode 100644 index 0000000..b9c2008 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic32.cc @@ -0,0 +1,657 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#include "graphic32.h" + +extern unsigned char SQRT[]; + +#define FULL_AA + +#define PRINT 0 + +typedef unsigned long TYPE; + +GraphicDevice32::GraphicDevice32(FlashDisplay *fd) : GraphicDevice(fd) +{ +} + +long +GraphicDevice32::allocColor(Color color) +{ + return (color.red)<<16 | (color.green)<<8 | (color.blue); +} + +void +GraphicDevice32::clearCanvas() +{ + TYPE pixel; + TYPE *point,*p; + long h, w,n; + + if (!bgInitialized) return; + + pixel = allocColor(backgroundColor); + + point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin; + w = clip_rect.xmax - clip_rect.xmin; + h = clip_rect.ymax - clip_rect.ymin; + + while (h--) { + p = point; + n = w; + while (n--) { + *p++ = pixel; + } + + point = (TYPE *)((char *)point + bpl); + } + + flashDisplay->flash_refresh = 1; + flashDisplay->clip_x = clip_rect.xmin; + flashDisplay->clip_y = clip_rect.ymin; + flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin; + flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin; +} + +#define RED_MASK 0xFF0000 +#define GREEN_MASK 0x00FF00 +#define BLUE_MASK 0x0000FF + +/* alpha = 0 : select c1, alpha = 255 select c2 */ +static inline unsigned long +mix_alpha(unsigned long c1, unsigned long c2, int alpha) +{ + long r1,r2,r; + long g1,g2,g; + long b1,b2,b; + + r1 = c1 & RED_MASK; + r2 = c2 & RED_MASK; + r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK; + + g1 = c1 & GREEN_MASK; + g2 = c2 & GREEN_MASK; + g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK; + + b1 = c1 & BLUE_MASK; + b2 = c2 & BLUE_MASK; + b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK; + + return (r|g|b); +} + +void +GraphicDevice32::fillLineAA(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line; + TYPE *point,pixel; + unsigned int alpha, start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + line = (TYPE *)(canvasBuffer + bpl*y); + + alpha = f->color.alpha; + pixel = f->color.pixel; + + if (alpha == ALPHA_OPAQUE) { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start]; + + if (start == end) { + *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255); + } else { + n = end-start; + if (start_alpha < 255) { + *point = mix_alpha(*point, pixel, start_alpha); + point++; + n--; + } + while (n > 0) { + *point = pixel; + point++; + n--; + } + if (end_alpha > 0) { + *point = mix_alpha(*point, pixel, end_alpha); + } + } + } else { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start]; + + if (start == end) { + *point = mix_alpha(*point, pixel, + ((start_alpha + end_alpha - 255) * alpha) >> 8); + } else { + n = end-start; + if (start_alpha < 255) { + *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8); + point++; + n--; + } + while (n > 0) { + *point = mix_alpha(*point, pixel, alpha); + point++; + n--; + } + if (end_alpha > 0) { + *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8); + } + } + } +} + +void +GraphicDevice32::fillLine(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line,*point; + TYPE pixel; + unsigned int alpha; + + if (clip(y,start,end)) return; + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + n = end-start; + pixel = f->color.pixel; + alpha = f->color.alpha; + if (alpha == ALPHA_OPAQUE) { + while (n--) { + *point = pixel; + point++; + } + } else { + while (n--) { + *point = mix_alpha(*point, pixel, alpha); + point++; + } + } +} + +void +GraphicDevice32::fillLineBitmap(FillStyleDef *f, long y, long start, long end) +{ + int n; + long x1,y1,dx,dy; + Matrix *m = &f->bitmap_matrix; + Bitmap *b = f->bitmap; + unsigned char *pixels; + TYPE *p; + Color *cmap; + long pixbpl; + TYPE pixel; + int offset; + unsigned char *alpha_table; + + /* safety test) */ + if (!b) return; + + if (clip(y,start,end)) return; + + start /= FRAC; + end /= FRAC; + n = end - start; + p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * sizeof(TYPE)); + + /* the coordinates in the image are normalized to 16 bits */ + x1 = (long) (m->a * start + m->b * y + m->tx); + y1 = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + pixels = b->pixels; + pixbpl = b->bpl; + cmap = f->cmap; + + if (b->alpha_buf == NULL) { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel; + *p = pixel; + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } else if (f->alpha_table) { + alpha_table = f->alpha_table; + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + pixel = cmap[pixels[offset]].pixel; + *p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]); + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } else { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + pixel = cmap[pixels[offset]].pixel; + *p = mix_alpha(*p, pixel, b->alpha_buf[offset]); + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } +} + +void +GraphicDevice32::fillLineLG(Gradient *grad, long y, long start, long end) +{ + long dr,r,v,r2; + register long n; + TYPE *line; + TYPE *point; + Color *cp,*ramp; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + r = (long) (m->a * start + m->b * y + m->tx); + dr = (long) (m->a); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + + r2 = r + n * dr; + if ( ((r | r2) & ~255) == 0 ) { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha); + point++; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + *point = (TYPE)ramp[v].pixel; + point++; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + cp = &ramp[v]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + r += dr; + } + } + } else { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha); + point++; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = (TYPE)ramp[v].pixel; + point++; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + cp = &ramp[v]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + r += dr; + } + } + } +} + +void +GraphicDevice32::fillLineRG(Gradient *grad, long y, long start, long end) +{ + long X,dx,r,Y,dy; + long dist2; + register long n; + Color *cp,*ramp; + TYPE *line; + TYPE *point; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + X = (long) (m->a * start + m->b * y + m->tx); + Y = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start == end) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r = SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255); + } else { + if (start_alpha < 255) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r = SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha); + point++; + X += dx; + Y += dy; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point = (TYPE)ramp[r].pixel; + point++; + X += dx; + Y += dy; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha); + } + } +#endif /* FULL_AA */ + + } else { + while (n--) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + cp = &ramp[r]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + X += dx; + Y += dy; + } + } +} + +void +GraphicDevice32::drawLine(long x1, long y1, long x2, long y2, long width) +{ + int n,adr,dx,dy,sx,color; + register int a; + register TYPE *pp; + int alpha; + + x1 = (x1) >> FRAC_BITS; + y1 = (y1) >> FRAC_BITS; + x2 = (x2) >> FRAC_BITS; + y2 = (y2) >> FRAC_BITS; + + if (y1 > y2 || (y1 == y2 && x1 > x2)) { + long tmp; + + tmp=x1; + x1=x2; + x2=tmp; + + tmp=y1; + y1=y2; + y2=tmp; + } + + if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return; + if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return; + if (x1 == x2 && y1 == y2) return; // Bad !!! + + if (y1 < clip_rect.ymin && y1 != y2) { + x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1); + y1 = clip_rect.ymin; + } + + if (y2 > clip_rect.ymax && y1 != y2) { + x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1); + y2 = clip_rect.ymax; + } + + if (x1 < x2) { + if (x1 < clip_rect.xmin && x1 != x2) { + y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1); + x1 = clip_rect.xmin; + } + + if (x2 > clip_rect.xmax && x1 != x2) { + y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1); + x2 = clip_rect.xmax; + } + } + + if (x1 > x2) { + if (x2 < clip_rect.xmin && x2 != x1) { + y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2); + x2 = clip_rect.xmin; + } + + if (x1 > clip_rect.xmax && x2 != x1) { + y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2); + x1 = clip_rect.xmax; + } + } + + // Check again + if (x1 == x2 && y1 == y2) return; + if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return; + if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return; + if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return; + if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return; + + sx=bpl >> 1; + adr=(y1 * sx + x1); + pp = (TYPE *)canvasBuffer + adr; + + dx = x2 - x1; + dy = y2 - y1; + + color = allocColor(foregroundColor); + alpha = foregroundColor.alpha; + + if (alpha == ALPHA_OPAQUE) { + +#define PUTPIXEL() \ + { \ + *pp=color; \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } else { +#define PUTPIXEL() \ + { \ + *pp=mix_alpha(*pp,color,alpha); \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } +} diff --git a/core/multimedia/opieplayer/libflash/graphic32.h b/core/multimedia/opieplayer/libflash/graphic32.h new file mode 100644 index 0000000..3d75a4d --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic32.h @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +class GraphicDevice32: public GraphicDevice { +private: + long GraphicDevice32::allocColor(Color color); + +public: + GraphicDevice32(FlashDisplay *fd); + + void clearCanvas(); + void fillLineAA(FillStyleDef *f, long y, long start, long end); + void fillLine(FillStyleDef *f, long y, long start, long end); + void fillLineBitmap(FillStyleDef *f, long y, long start, long end); + void fillLineLG(Gradient *grad, long y, long start, long end); + void fillLineRG(Gradient *grad, long y, long start, long end); + void drawLine(long x1, long y1, long x2, long y2, long width); +}; diff --git a/core/multimedia/opieplayer/libflash/jconfig.h b/core/multimedia/opieplayer/libflash/jconfig.h new file mode 100644 index 0000000..9594ec5 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/jconfig.h @@ -0,0 +1,45 @@ +/* jconfig.h. Generated automatically by configure. */ +/* jconfig.cfg --- source file edited by configure script */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +#undef void +#undef const +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +/* Define this if you get warnings about undefined structures. */ +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED +#define INLINE __inline__ +/* These are for configuring the JPEG memory manager. */ +#undef DEFAULT_MAX_MEM +#undef NO_MKTEMP + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#undef TWO_FILE_COMMANDLINE +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE + +/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ +#undef PROGRESS_REPORT + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/core/multimedia/opieplayer/libflash/jerror.h b/core/multimedia/opieplayer/libflash/jerror.h new file mode 100644 index 0000000..fc2fffe --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/jerror.h @@ -0,0 +1,291 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, there are legal restrictions on arithmetic coding") +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/core/multimedia/opieplayer/libflash/jmorecfg.h b/core/multimedia/opieplayer/libflash/jmorecfg.h new file mode 100644 index 0000000..54a7d1c --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/jmorecfg.h @@ -0,0 +1,363 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +typedef long INT32; +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/core/multimedia/opieplayer/libflash/jpeglib.h b/core/multimedia/opieplayer/libflash/jpeglib.h new file mode 100644 index 0000000..d1be8dd --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/jpeglib.h @@ -0,0 +1,1096 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". + */ + +#define JPEG_LIB_VERSION 62 /* Version 6b */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values of 1,2,4,8 are likely to be supported. Note that different + * components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.doc concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/core/multimedia/opieplayer/libflash/libflash.pro b/core/multimedia/opieplayer/libflash/libflash.pro new file mode 100644 index 0000000..d144f0b --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflash.pro @@ -0,0 +1,15 @@ +TEMPLATE = lib +CONFIG += qt warn_on release +HEADERS = libflashplugin.h libflashpluginimpl.h +SOURCES = libflashplugin.cpp libflashpluginimpl.cpp \ + adpcm.cc character.cc flash.cc graphic16.cc matrix.cc script.cc \ + sprite.cc bitmap.cc cxform.cc font.cc graphic24.cc movie.cc \ + shape.cc sqrt.cc button.cc displaylist.cc graphic.cc graphic32.cc \ + program.cc sound.cc text.cc +TARGET = flashplugin +DESTDIR = ../../plugins/codecs +INCLUDEPATH += $(QPEDIR)/include .. +DEPENDPATH += ../$(QPEDIR)/include .. +LIBS += -lqpe +VERSION = 1.0.0 + diff --git a/core/multimedia/opieplayer/libflash/libflashplugin.cpp b/core/multimedia/opieplayer/libflash/libflashplugin.cpp new file mode 100644 index 0000000..538c695 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflashplugin.cpp @@ -0,0 +1,223 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "libflashplugin.h" + +#if 0 + +bool LibFlashPlugin::audioReadSamples( short *output, int channel, long samples, int stream ) { +} + + +bool LibFlashPlugin::audioReReadSamples( short *output, int channel, long samples, int stream ) { +} + + +bool LibFlashPlugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) { + samplesRead = samples; +} + + +bool LibFlashPlugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) { +} + + +bool LibFlashPlugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) { +} + + +bool LibFlashPlugin::videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) { +/* + int format = MPEG3_RGB565; + switch ( color_model ) { + case RGB565: format = MPEG3_RGB565; break; + case RGBA8888: format = MPEG3_RGBA8888; break; + case BGRA8888: format = MPEG3_BGRA8888; break; + } +*/ +} + + +bool LibFlashPlugin::videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) { +} + + +FlashHandle file; +FlashDisplay *fd; + +#endif + + +LibFlashPlugin::LibFlashPlugin() { + file = NULL; + fd = 0; +} +#include +#include +static int readFile(const char *filename, char **buffer, long *size) +{ + FILE *in; + char *buf; + long length; + + printf("read files\n"); + + in = fopen(filename,"r"); + if (in == 0) { + perror(filename); + return -1; + } + fseek(in,0,SEEK_END); + length = ftell(in); + rewind(in); + buf = (char *)malloc(length); + fread(buf,length,1,in); + fclose(in); + + *size = length; + *buffer = buf; + + return length; +} + +static void showUrl(char *url, char * /*target*/, void * /*client_data*/) { + printf("get url\n"); + printf("GetURL : %s\n", url); +} + +static void getSwf(char *url, int level, void *client_data) { + FlashHandle flashHandle = (FlashHandle) client_data; + char *buffer; + long size; + + printf("get swf\n"); + + printf("LoadMovie: %s @ %d\n", url, level); + if (readFile(url, &buffer, &size) > 0) { + FlashParse(flashHandle, level, buffer, size); + } +} + +bool LibFlashPlugin::open( const QString& fileName ) { + + printf("opening file\n"); + + delete fd; + fd = new FlashDisplay; + fd->pixels = new int[320*240*4]; + fd->width = 200; + fd->bpl = 320*2; + fd->height = 300; + fd->depth = 16; + fd->bpp = 2; + fd->flash_refresh = 25; + fd->clip_x = 0; + fd->clip_y = 0; + fd->clip_width = 0; + fd->clip_height = 0; + + char *buffer; + long size; + int status; + struct FlashInfo fi; + + if (readFile(fileName.latin1(), &buffer, &size) < 0) + exit(2); + + if (!(file = FlashNew())) + exit(1); + + do + status = FlashParse(file, 0, buffer, size); + while (status & FLASH_PARSE_NEED_DATA); + + free(buffer); + FlashGetInfo(file, &fi); + //FlashSettings(flashHandle, PLAYER_LOOP); + FlashGraphicInit(file, fd); + FlashSoundInit(file, "/dev/dsp"); + FlashSetGetUrlMethod(file, showUrl, 0); + FlashSetGetSwfMethod(file, getSwf, (void*)file); + + printf("opened file\n"); +} + +// If decoder doesn't support audio then return 0 here +bool LibFlashPlugin::audioSetSample( long sample, int stream ) { return TRUE; } +long LibFlashPlugin::audioGetSample( int stream ) { return 0; } +//bool LibFlashPlugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) { return TRUE; } +//bool LibFlashPlugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) { return FALSE; } +bool LibFlashPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ) { return FALSE; } +//bool LibFlashPlugin::audioReadSamples( short *output, int channel, long samples, int stream ) { return TRUE; } +//bool LibFlashPlugin::audioReReadSamples( short *output, int channel, long samples, int stream ) { return TRUE; } + +// If decoder doesn't support video then return 0 here +int LibFlashPlugin::videoStreams() { return 1; } +int LibFlashPlugin::videoWidth( int stream ) { return 300; } +int LibFlashPlugin::videoHeight( int stream ) { return 200; } +double LibFlashPlugin::videoFrameRate( int stream ) { return 25.0; } +int LibFlashPlugin::videoFrames( int stream ) { return 1000000; } +bool LibFlashPlugin::videoSetFrame( long frame, int stream ) { return TRUE; } +long LibFlashPlugin::videoGetFrame( int stream ) { return 0; } +bool LibFlashPlugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) { return TRUE; } +#include +bool LibFlashPlugin::videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) { + struct timeval wd; + FlashEvent fe; + +/* + delete fd; + fd = new FlashDisplay; + fd->pixels = output_rows[0]; + fd->width = 300; // out_w; + fd->bpl = 640; // out_w*2; + fd->height = 200;//out_h; + fd->depth = 16; + fd->bpp = 2; + fd->flash_refresh = 50; + fd->clip_x = 0;//in_x; + fd->clip_y = 0;//in_y; + fd->clip_width = 300;//in_w; + fd->clip_height = 200;//in_h; + FlashGraphicInit(file, fd); +*/ + + long cmd = FLASH_WAKEUP; + FlashExec(file, cmd, 0, &wd); + + fe.type = FeRefresh; + cmd = FLASH_EVENT; + FlashExec(file, cmd, &fe, &wd); +/* + for (int i = 0; i < out_h; i++) + memcpy( output_rows[i], (char*)fd->pixels + i*fd->bpl, QMIN( fd->width * fd->bpp, out_w * fd->bpp ) ); +*/ + memcpy( output_rows[0], (char*)fd->pixels, out_w * out_h * 2 ); +} + +bool LibFlashPlugin::videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) { return TRUE; } + +// Profiling +double LibFlashPlugin::getTime() { return 0.0; } + +// Ignore if these aren't supported +bool LibFlashPlugin::setSMP( int cpus ) { return TRUE; } +bool LibFlashPlugin::setMMX( bool useMMX ) { return TRUE; } + + diff --git a/core/multimedia/opieplayer/libflash/libflashplugin.h b/core/multimedia/opieplayer/libflash/libflashplugin.h new file mode 100644 index 0000000..532bca2 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflashplugin.h @@ -0,0 +1,96 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LIBFLASH_PLUGIN_H +#define LIBFLASH_PLUGIN_H + + +#include +#include +#include "flash.h" +#include "mediaplayerplugininterface.h" + + +class LibFlashPlugin : public MediaPlayerDecoder { + +public: + LibFlashPlugin(); + ~LibFlashPlugin() { close(); } + + const char *pluginName() { return "LibFlashPlugin: " PLUGIN_NAME " " FLASH_VERSION_STRING; } + const char *pluginComment() { return "This is the libflash library: " PLUGIN_NAME " " FLASH_VERSION_STRING; } + double pluginVersion() { return 1.0; } + + bool isFileSupported( const QString& fileName ) { return fileName.right(4) == ".swf"; } + bool open( const QString& fileName ); + bool close() { FlashClose( file ); file = NULL; return TRUE; } + bool isOpen() { return file != NULL; } + const QString &fileInfo() { return strInfo = qApp->translate( "MediaPlayer", "No Information Available", "media plugin text" ); } + + // If decoder doesn't support audio then return 0 here + int audioStreams() { return 1; } + int audioChannels( int /*stream*/ ) { return 2; } + int audioFrequency( int /*stream*/ ) { return 44100; } + int audioSamples( int /*stream*/ ) { return 1000000; } + bool audioSetSample( long sample, int stream ); + long audioGetSample( int stream ); + //bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ); + //bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ); + bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ); + //bool audioReadSamples( short *output, int channel, long samples, int stream ); + //bool audioReReadSamples( short *output, int channel, long samples, int stream ); + + // If decoder doesn't support video then return 0 here + int videoStreams(); + int videoWidth( int stream ); + int videoHeight( int stream ); + double videoFrameRate( int stream ); + int videoFrames( int stream ); + bool videoSetFrame( long frame, int stream ); + long videoGetFrame( int stream ); + bool videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ); + bool videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ); + bool videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ); + + // Profiling + double getTime(); + + // Ignore if these aren't supported + bool setSMP( int cpus ); + bool setMMX( bool useMMX ); + + // Capabilities + bool supportsAudio() { return TRUE; } + bool supportsVideo() { return TRUE; } + bool supportsYUV() { return TRUE; } + bool supportsMMX() { return TRUE; } + bool supportsSMP() { return TRUE; } + bool supportsStereo() { return TRUE; } + bool supportsScaling() { return TRUE; } + +private: + FlashHandle file; + FlashDisplay *fd; + QString strInfo; + +}; + + +#endif + diff --git a/core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp b/core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp new file mode 100644 index 0000000..af2c07e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "libflashplugin.h" +#include "libflashpluginimpl.h" + + +LibFlashPluginImpl::LibFlashPluginImpl() + : libflashplugin(0), ref(0) +{ +} + + +LibFlashPluginImpl::~LibFlashPluginImpl() +{ + if ( libflashplugin ) + delete libflashplugin; +} + + +MediaPlayerDecoder *LibFlashPluginImpl::decoder() +{ + if ( !libflashplugin ) + libflashplugin = new LibFlashPlugin; + return libflashplugin; +} + + +MediaPlayerEncoder *LibFlashPluginImpl::encoder() +{ + return NULL; +} + + +#ifndef QT_NO_COMPONENT + + +QRESULT LibFlashPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) ) + *iface = this, (*iface)->addRef(); + return QS_OK; +} + + +Q_EXPORT_INTERFACE() +{ + Q_CREATE_INSTANCE( LibFlashPluginImpl ) +} + + +#endif + diff --git a/core/multimedia/opieplayer/libflash/libflashpluginimpl.h b/core/multimedia/opieplayer/libflash/libflashpluginimpl.h new file mode 100644 index 0000000..b5cc869 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflashpluginimpl.h @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LIBFLASH_PLUGIN_IMPL_H +#define LIBFLASH_PLUGIN_IMPL_H + + +#include "../mediaplayerplugininterface.h" + + +class LibFlashPlugin; + + +class LibFlashPluginImpl : public MediaPlayerPluginInterface +{ +public: + LibFlashPluginImpl(); + virtual ~LibFlashPluginImpl(); + +#ifndef QT_NO_COMPONENT + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT + +#endif + + virtual MediaPlayerDecoder *decoder(); + virtual MediaPlayerEncoder *encoder(); + +private: + LibFlashPlugin *libflashplugin; + ulong ref; +}; + + +#endif + diff --git a/core/multimedia/opieplayer/libflash/matrix.cc b/core/multimedia/opieplayer/libflash/matrix.cc new file mode 100644 index 0000000..0d8c82c --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/matrix.cc @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "matrix.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +Matrix::Matrix() +{ + a = 1.0; + d = 1.0; + b = c = 0.0; + tx = ty = 0; +} + +Matrix Matrix::operator*(Matrix m) +{ + Matrix mat; + + mat.a = this->a * m.a + this->b * m.c; + mat.b = this->a * m.b + this->b * m.d; + mat.c = this->c * m.a + this->d * m.c; + mat.d = this->c * m.b + this->d * m.d; + + mat.tx = this->getX(m.tx,m.ty); + mat.ty = this->getY(m.tx,m.ty); + + return mat; +} + +Matrix Matrix::invert() +{ + Matrix mat; + float det; + + det = a*d-b*c; + + mat.a = d/det; + mat.b = -b/det; + mat.c = -c/det; + mat.d = a/det; + + mat.tx = - (long)(mat.a * tx + mat.b * ty); + mat.ty = - (long)(mat.c * tx + mat.d * ty); + + return mat; +} diff --git a/core/multimedia/opieplayer/libflash/matrix.h b/core/multimedia/opieplayer/libflash/matrix.h new file mode 100644 index 0000000..83b54c2 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/matrix.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _MATRIX_H_ +#define _MATRIX_H_ + +struct Matrix { + float a,b,c,d; + long tx,ty; +public: + Matrix operator*(Matrix); + Matrix invert(); + Matrix(); + +#ifdef DUMP + void dump(BitStream *bs); +#endif + + inline + long Matrix::getX(long x, long y) + { + return (long) (x*a+y*b+tx); + }; + + inline + long Matrix::getY(long x, long y) + { + return (long) (x*c+y*d+ty); + }; + +}; + +#endif /* _MATRIX_H_ */ diff --git a/core/multimedia/opieplayer/libflash/movie.cc b/core/multimedia/opieplayer/libflash/movie.cc new file mode 100644 index 0000000..349e43b --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/movie.cc @@ -0,0 +1,171 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// +#include "movie.h" + +FlashMovie::FlashMovie() +{ + gd = NULL; + sm = NULL; + getSwf = NULL; + getUrl = NULL; + cursorOnOff = NULL; + buttons_updated = 0; + scheduledTime.tv_sec = -1; + cur_focus = NULL; + lost_over = NULL; + msPerFrame = 0; + + /* mouse handling */ + mouse_active = 0; + mouse_x = -1; + mouse_y = -1; + button_pressed = 0; + refresh = 1; +} + +FlashMovie::~FlashMovie() +{ + CInputScript *n; + + while (main != NULL) { + n = main->next; + delete main; + main = n; + } + + if (gd) delete gd; + if (sm) delete sm; +} + +int +FlashMovie::processMovie(GraphicDevice *gd, SoundMixer *sm) +{ + CInputScript *script; + int wakeUp = 0; + + if (sm && sm->playSounds()) { + wakeUp = 1; + } + for (script = this->main; script != NULL; script = script->next) { + if (script->program == NULL) continue; + if (script->program->nbFrames == 0) continue; + if (script->program->processMovie(gd,sm)) { + wakeUp = 1; + } + } + renderMovie(); + return wakeUp; +} + +int +FlashMovie::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event) +{ + int wakeUp = 0; + + if (sm && sm->playSounds()) { + wakeUp = 1; + } + if (this->main == 0) return 0; + if (this->main->program == 0) return 0; + if (this->main->program->handleEvent(gd, sm, event)) { + wakeUp = 1; + } + renderMovie(); + return wakeUp; +} + +/* current focus bigger and translated if needed */ +void +FlashMovie::renderFocus() +{ + Rect rect,boundary; + Matrix mat; + + if (mouse_active || !cur_focus) return; + + /* rect is the bbox in screen coordinates */ + + // Compute the bounding box in screen coordinates + cur_focus->character->getBoundingBox(&boundary,cur_focus); + mat = (*gd->adjust) * cur_focus->renderMatrix; + transformBoundingBox(&rect, &mat, &boundary, 1); + + gd->drawBox(rect.xmin, rect.ymin, rect.xmax, rect.ymax); +} + +void +FlashMovie::renderMovie() +{ + CInputScript *script,*prev,*next; + Rect clipping; + Matrix identity; + + clipping.reset(); + + // First pass to update the clipping region + for (script = this->main; script != NULL; script = script->next) { + if (script->level == -1) { + clipping.xmin = -32768; + clipping.ymin = -32768; + clipping.xmax = 32767; + clipping.ymax = 32767; + continue; + } + if (script->program == NULL) continue; + if (script->program->dl->bbox.xmin == LONG_MAX) continue; + transformBoundingBox(&clipping, &identity, &script->program->dl->bbox, 0); + script->program->render = 0; + } + + if (clipping.xmin == LONG_MAX) return; + + // Update the clipping region + gd->updateClippingRegion(&clipping); + gd->clearCanvas(); + + // Second pass to render the movie + for (script = this->main; script != NULL; script = script->next) { + if (script->level == -1) continue; + if (script->program == NULL) continue; + script->program->dl->render(gd); + } + renderFocus(); + + // Final pass to delete some movies + script = this->main; + prev = 0; + while (script != NULL) { + if (script->level == -1) { + next = script->next; + if (prev == 0) { + this->main = next; + } else { + prev->next = next; + } + delete script; + script = next; + } else { + prev = script; + script = script->next; + } + } +} diff --git a/core/multimedia/opieplayer/libflash/movie.h b/core/multimedia/opieplayer/libflash/movie.h new file mode 100644 index 0000000..d83ce79 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/movie.h @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _MOVIE_H_ +#define _MOVIE_H_ + +#include "swf.h" + +struct FlashMovie { + /* true if a button has been moved */ + int buttons_updated; + + /* current keyboard focus */ + DisplayListEntry *cur_focus; + + /* mouse state */ + long mouse_active; + long mouse_x; + long mouse_y; + int button_pressed; + + Button *lost_over; + + /* a button can return to a given state after some time */ + FlashEvent scheduledEvent; + struct timeval scheduledTime; + + int refresh; + + CInputScript *main; + long msPerFrame; + GraphicDevice *gd; + SoundMixer *sm; + + void (*getUrl)(char *,char *, void *); + void *getUrlClientData; + + void (*getSwf)(char *url, int level, void *clientData); + void *getSwfClientData; + + void (*cursorOnOff)(int , void *); + void *cursorOnOffClientData; + + FlashMovie(); + ~FlashMovie(); + int processMovie(GraphicDevice *gd, SoundMixer *sm); + int handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event); + void renderMovie(); + void renderFocus(); +}; + +#endif /* _MOVIE_H_ */ diff --git a/core/multimedia/opieplayer/libflash/program.cc b/core/multimedia/opieplayer/libflash/program.cc new file mode 100644 index 0000000..c6e8c0f --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/program.cc @@ -0,0 +1,921 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#define NOTHING 0x0 +#define WAKEUP 0x1 +#define GOTO 0x2 +#define REFRESH 0x4 + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +int debug = 0; + +Program::Program(FlashMovie *movie, long n) +{ + long f; + + this->movie = movie; + + totalFrames = 0; + + dl = new DisplayList(movie); + if (dl == NULL) return; + frames = new Frame[n]; + if (frames == NULL) { + delete dl; + return; + } + + nbFrames = 0; + totalFrames = n; + currentFrame = 0; + loadingFrame = 0; + movieWait = 1; + nextFrame = currentFrame; + for(f = 0; f < n; f++) + { + frames[f].controls = 0; + frames[f].label = NULL; + } + + movieStatus = MoviePlay; + settings = 0; +} + +Program::~Program() +{ + int i; + Control *ctrl, *ctrl1; + + delete dl; + + if (frames != NULL) { + for(i=0;inext; + ctrl->next = NULL; + delete ctrl; + ctrl = ctrl1; + } + } + + delete[] frames; + } +} + +void +Program::validateLoadingFrame() +{ + nbFrames = loadingFrame; + loadingFrame++; + movieWait = 0; +} + +Frame * +Program::getFrames() +{ + return frames; +} + +long +Program::getNbFrames() +{ + return nbFrames; +} + +DisplayList * +Program::getDisplayList() +{ + return dl; +} + +long +Program::getCurrentFrame() +{ + return currentFrame; +} + +void +Program::setCurrentFrame(long n) +{ + currentFrame = n; + nextFrame = n; + //refresh = 1; +} + +void +Program::gotoFrame(GraphicDevice *gd, long frame) +{ + long f; + + //printf("GotoFrame %d (Current = %d)\n", frame, currentFrame); + dl->clearList(); + + for(f=0; f <= frame; f++) { + runFrame(gd, 0, f, 0); + } +} + +long +Program::runFrame(GraphicDevice *gd, SoundMixer *sm, long f, long action) +{ + Control *ctrl; + Character *character; + Matrix *matrix; + Cxform *cxform; + long status = NOTHING; + long update = 0; + char *name; + +#if PRINT&1 + if (action) printf("Prog %x (dl=%x): Frame N° %d/%d\n", this, this->dl, f, nbFrames-1); +#endif + movie->buttons_updated = 0; + + for(ctrl = frames[f].controls; ctrl; ctrl = ctrl->next) + { + switch (ctrl->type) + { + case ctrlPlaceObject: + case ctrlPlaceObject2: + character = 0; + matrix = 0; + cxform = 0; + name = ""; + if (ctrl->flags & placeHasCharacter) { + character = ctrl->character; + } + if (ctrl->flags & placeHasMatrix) { + matrix = &ctrl->matrix; + } + if (ctrl->flags & placeHasColorXform) { + cxform = &ctrl->cxform; + } + if (ctrl->flags & placeHasName) { + name = ctrl->name; + } + if (!ctrl->clipDepth) { // Ignore + dl->placeObject(gd,character, ctrl->depth, matrix, cxform, name); + update = 1; + } + break; + case ctrlRemoveObject: + character = ctrl->character; + + if (!character) break; // Should not happen + + dl->removeObject(gd, character, ctrl->depth); + if (action) { + character->reset(); + update = 1; + } + break; + case ctrlRemoveObject2: + character = dl->removeObject(gd,NULL, ctrl->depth); + if (character && action) { + character->reset(); + update = 1; + } + break; + // Actions + case ctrlDoAction: + if (action) { + status = doAction(gd, ctrl->actionRecords, sm); + } + break; + case ctrlStartSound: + if (action && sm) { + sm->startSound( (Sound *)ctrl->character ); + } + break; + case ctrlStopSound: + if (action && sm) { + sm->stopSounds(); + } + break; + case ctrlBackgroundColor: + if (action) { + if (gd->setBackgroundColor(ctrl->color)) { + dl->bbox.xmin = -32768; + dl->bbox.ymin = -32768; + dl->bbox.xmax = 32768; + dl->bbox.ymax = 32768; + } + } + break; + } + } + if (movie->buttons_updated) { + dl->updateButtons(movie); + } + + if (status & GOTO) { + if (nextFrame < nbFrames) { + gotoFrame(gd,nextFrame); + if (nextFrame != f) + if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame); + update = 1; + } + } + +#if PRINT&1 + if (action) printf("Frame N° %d ready\n", f); +#endif + return update; +} + +long +Program::nestedMovie(GraphicDevice *gd, SoundMixer *sm, Matrix *mat, Cxform *cxform) +{ + if (movieStatus == MoviePlay) { + // Movie Beeing Played + advanceFrame(); + if (currentFrame == 0) { + dl->clearList(); + } + runFrame(gd, sm, currentFrame); + if (nbFrames == 1) { + pauseMovie(); + } + } + + return (movieStatus == MoviePlay); +} + +long +Program::processMovie(GraphicDevice *gd, SoundMixer *sm) +{ + int wakeUp = 0; + +#if PRINT&1 + printf("Prog %x (dl=%x): Current = %d Next = %d Wait = %d Status = %d\n", this, this->dl, currentFrame, nextFrame, movieWait, movieStatus); +#endif + + if (movieStatus == MoviePlay && movieWait == 0) { + // Movie Beeing Played + advanceFrame(); + if (currentFrame == 0) { + dl->clearList(); + } + wakeUp |= runFrame(gd, sm, currentFrame); + wakeUp |= dl->updateSprites(); + if (nextFrame == nbFrames) { + if (nbFrames != totalFrames) { + movieWait = 1; + } else if ((settings & PLAYER_LOOP) == 0) { + pauseMovie(); + } + } + } else { + wakeUp |= dl->updateSprites(); + } + + if (wakeUp) { + render = 1; + } + + return (wakeUp || movieStatus == MoviePlay); +} + +/* timer (ms) -1 = delete timer */ +void setFlashTimer(struct timeval *tv, int time_ms) +{ + if (time_ms == -1) { + tv->tv_sec = -1; + } else { + gettimeofday(tv,0); + + tv->tv_usec += time_ms*1000; + while (tv->tv_usec > 1000000) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } + } +} + +int checkFlashTimer(struct timeval *tv) +{ + struct timeval now; + + if (tv->tv_sec == -1) return 0; + + gettimeofday(&now,0); + return (now.tv_sec > tv->tv_sec || + (now.tv_sec == tv->tv_sec && now.tv_usec >= tv->tv_usec)); +} + +/* bbox */ +typedef struct { + long x1,y1,x2,y2; +} ButtonBoundingBox; + + +static void button_bbox_func(void *id, long y, long start, long end) +{ + ButtonBoundingBox *h = (ButtonBoundingBox *) id; + + if (y < h->y1) h->y1 = y; + if (y > h->y2) h->y2 = y; + if (start < h->x1) h->x1 = start; + if (end > h->x2) h->x2 = end; +} + +void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e) +{ + ButtonBoundingBox bb; + + bb.x1 = LONG_MAX; + bb.y1 = LONG_MAX; + bb.x2 = LONG_MIN; + bb.y2 = LONG_MIN; + + e->character->getRegion(movie->gd,&e->renderMatrix,&bb,button_bbox_func); + + rect->xmin = bb.x1 / FRAC; + rect->xmax = bb.x2 / FRAC; + rect->ymin = bb.y1; + rect->ymax = bb.y2; +} + +void transform_coords(long *x_ptr,long *y_ptr, long cx, long cy, long dx, long dy) +{ + long x,y,x1,y1; + x = *x_ptr; + y = *y_ptr; + + x -= cx; + y -= cy; + + if (dx < 0) { + /* left */ + x1 = - x; + y1 = y; + } else if (dy < 0) { + /* up */ + y1 = x; + x1 = -y; + } else if (dy > 0) { + /* down */ + y1 = x; + x1 = y; + } else { + /* right */ + x1 = x; + y1 = y; + } + + *x_ptr = x1; + *y_ptr = y1; +} + +typedef struct { + FlashMovie *movie; + DisplayListEntry *emin,*cur_focus; + long dmin; + long w,cx,cy,dx,dy; +} ButtonFocus; + +static int button_focus(void *opaque, Program *prg, DisplayListEntry *e) +{ + ButtonFocus *h=(ButtonFocus *)opaque; + Rect rect; + long d,x,y; + + if (e != h->cur_focus) { + computeBBox(h->movie,&rect,e); + x = (rect.xmin + rect.xmax) / 2; + y = (rect.ymin + rect.ymax) / 2; + + /* transform the coords so that the angular sector is directed to the right */ + transform_coords(&x,&y,h->cx,h->cy,h->dx,h->dy); + + /* inside it ? */ + if ( x >= 0 && + (y - x - h->w) <= 0 && + (y + x + h->w) >= 0) { + d = x*x + y*y; + + if (d < h->dmin) { + h->dmin = d; + h->emin = e; + } + } + } + return 0; +} + +DisplayListEntry *moveFocus(FlashMovie *movie, long dx, long dy, + DisplayListEntry *cur_focus) +{ + Rect cur_rect; + ButtonFocus h; + + h.movie = movie; + h.dx = dx; + h.dy = dy; + + computeBBox(movie,&cur_rect,cur_focus); + /* center */ + h.cx = (cur_rect.xmin + cur_rect.xmax) / 2; + h.cy = (cur_rect.ymin + cur_rect.ymax) / 2; + + /* width/2 of the 45 degrees angular sector */ + if (dy != 0) { + /* for vertical displacement, we have a larger width */ + h.w = (cur_rect.xmax - cur_rect.xmin) / 2; + } else { + /* zero width for horizontal displacement */ + h.w = 0; + } + + /* now we select the nearest button in the angular sector */ + h.dmin = LONG_MAX; + h.emin = NULL; + h.cur_focus = cur_focus; + + exploreButtons(movie, &h, button_focus); + + return h.emin; +} + +static int button_newfocus(void *opaque, Program *prg, DisplayListEntry *e) +{ + * (DisplayListEntry **)opaque = e; + return 2; +} + +static int button_nextfocus(void *opaque, Program *prg, DisplayListEntry *e) +{ + static int found = 0; + DisplayListEntry **focus; + + focus = (DisplayListEntry **)opaque; + if (found) { + *focus = e; + found = 0; + return 2; + } + if (e == *focus) { + found = 1; + } + return 0; +} + + +/* XXX: should not be here (one level upper) */ +long +Program::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *fe) +{ + ActionRecord *action; + Program *prog; + long status = 0; + DisplayListEntry *cur_focus, *new_focus; + long dx,dy; + int refresh; + + refresh = 0; + + switch(fe->type) { + + case FeKeyRelease: + if (movie->mouse_active == 0) { + + if (movie->cur_focus) { + movie->cur_focus->owner->updateBoundingBox(movie->cur_focus); + movie->cur_focus->renderState = stateOver; + movie->cur_focus->owner->updateBoundingBox(movie->cur_focus); + } + } + break; + + case FeKeyPress: + + movie->mouse_active = 0; + + /* find the button which has the focus */ + cur_focus = movie->cur_focus; + + if (fe->key == FeKeyEnter) { + /* selection */ + if (cur_focus) { + /* select the button */ + cur_focus->owner->updateBoundingBox(cur_focus); + cur_focus->renderState = stateDown; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + + movie->scheduledEvent.type = FeKeyRelease; + movie->scheduledEvent.key = FeKeyEnter; + + setFlashTimer(&movie->scheduledTime, 250); /* 250 ms down */ + } + } else { + /* displacement */ + + if (cur_focus == NULL) { + /* no current focus : set one */ + exploreButtons(movie, &cur_focus, button_newfocus); + if (cur_focus) { + cur_focus->renderState = stateOver; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + } + movie->cur_focus = cur_focus; + } else { + /* move the focus (test) */ + switch(fe->key) { + case FeKeyNext: + /* Next available */ + cur_focus->owner->updateBoundingBox(cur_focus); + cur_focus->renderState = stateUp; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + exploreButtons(movie, &cur_focus, button_nextfocus); + if (cur_focus) { + cur_focus->renderState = stateOver; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + } + movie->cur_focus = cur_focus; + dx = 0; + dy = 0; + break; + case FeKeyUp: + dx = 0; + dy = -1; + break; + case FeKeyDown: + dx = 0; + dy = 1; + break; + case FeKeyLeft: + dx = -1; + dy = 0; + break; + case FeKeyRight: + dx = 1; + dy = 0; + break; + default: + /* should not happen */ + dx = 0; + dy = 0; + break; + } + + if (dx != 0 || dy != 0) { + + new_focus = moveFocus(movie, dx, dy, cur_focus); + if (new_focus) { + cur_focus->owner->updateBoundingBox(cur_focus); + cur_focus->renderState = stateUp; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + + if (computeActions(movie, &prog, &action)) { + status |= prog->doAction(gd, action, sm); + } + + new_focus->renderState = stateOver; + ((Button *)new_focus->character)->updateButtonState(new_focus); + movie->cur_focus = new_focus; + new_focus->owner->updateBoundingBox(new_focus); + } else { + return 0; + } + } + } + if (movie->cur_focus == NULL) return 0; + } + break; + + case FeMouseMove: + movie->mouse_active = 1; + movie->mouse_x = fe->x * FRAC; + movie->mouse_y = fe->y * FRAC; + dl->updateButtons(movie); + break; + + case FeButtonPress: + movie->mouse_active = 1; + movie->button_pressed = 1; + dl->updateButtons(movie); + break; + + case FeButtonRelease: + movie->mouse_active = 1; + movie->button_pressed = 0; + dl->updateButtons(movie); + break; + + default: + return 0; + } + + if (computeActions(movie, &prog, &action)) { + status |= prog->doAction(gd, action, sm); + } + + if (status & REFRESH) { + status |= WAKEUP; + refresh = 1; + } + if (status & GOTO) { + if (nextFrame < nbFrames) { + gotoFrame(gd, nextFrame); + if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame); + refresh = 1; + } + } + + if (refresh) { + dl->updateSprites(); + render = 1; + } + return (refresh || movieStatus == MoviePlay); +} + +long +Program::doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *sm) +{ + long status = NOTHING; + long f; + char *target = ""; + long skip = 0; + + while(action) + { + if (skip) skip--; + else + switch (action->action) + { + case ActionPlaySound: +#if PRINT&2 + printf("Prog %x : PlaySound\n", this); +#endif + if (sm) { + sm->startSound(action->sound); + } + status |= WAKEUP; + break; + case ActionRefresh: +#if PRINT&2 + printf("Prog %x : Refresh\n", this); +#endif + status |= REFRESH; + break; + case ActionGotoFrame: +#if PRINT&2 + printf("Prog %x : GotoFrame %d\n", this, action->frameIndex); +#endif + if (target[0] == 0) { + if (action->frameIndex < nbFrames) { + currentFrame = action->frameIndex; + pauseMovie(); + status |= WAKEUP|GOTO; + } + } + break; + case ActionGetURL: +#if PRINT&2 + printf("Prog %x : GetURL %s target = %s\n", this, action->url, action->target); +#endif + { + int len,level; + len = strlen(action->target); + + if (len > 6 && memcmp(action->target,"_level", 6) == 0) { + level = atoi(action->target + 6); + loadNewSwf(movie, action->url, level); + } else { + if (movie->getUrl) { + movie->getUrl(action->url, action->target, movie->getUrlClientData); + } + } + } + break; + case ActionNextFrame: + nextFrame = currentFrame+1; + movieStatus = MoviePlay; + status |= WAKEUP; + break; + case ActionPrevFrame: + nextFrame = currentFrame-1; + status |= WAKEUP|GOTO; + break; + case ActionPlay: +#if PRINT&2 + printf("Prog %x : Play\n", this); +#endif + if (target[0] == 0) { + movieStatus = MoviePlay; + if ((status & GOTO) == 0) { + if (currentFrame == nextFrame) advanceFrame(); + } + status |= WAKEUP; + } + break; + case ActionStop: +#if PRINT&2 + printf("Prog %x : Stop\n", this); +#endif + if (target[0] == 0) { + movieStatus = MoviePaused; + nextFrame = currentFrame; + } + break; + case ActionToggleQuality: + break; + case ActionStopSounds: + if (sm) { + sm->stopSounds(); + } + break; + case ActionWaitForFrame: + if (action->frameIndex >= nbFrames) { + skip = action->skipCount; + } + break; + case ActionSetTarget: +#if PRINT&2 + printf("Prog %x : SetTarget '%s'\n", this, action->target); +#endif + target = action->target; + break; + case ActionGoToLabel: +#if PRINT&2 + printf("Prog %x : GotoFrame '%s'\n", this, action->frameLabel); +#endif + f = searchFrame(gd, action->frameLabel, target); + if (f >= 0) { + currentFrame = f; + pauseMovie(); + status |= WAKEUP|GOTO; + } else { + status |= REFRESH; + } + break; + } + action = action->next; + } + return status; +} + +void +Program::setCurrentFrameLabel(char *label) +{ + frames[loadingFrame].label = label; +} + +void +Program::rewindMovie() +{ + currentFrame = 0; + nextFrame = 0; +} + +void +Program::pauseMovie() +{ + movieStatus = MoviePaused; + nextFrame = currentFrame; +} + +void +Program::continueMovie() +{ + movieStatus = MoviePlay; +} + +void +Program::nextStepMovie() +{ + if (movieStatus == MoviePaused) { + advanceFrame(); + } +} + +void +Program::advanceFrame() +{ + currentFrame = nextFrame; + nextFrame = currentFrame+1; + if (currentFrame == nbFrames) { + currentFrame = 0; + nextFrame = 0; + movieStatus = MoviePlay; + } +} + +void +Program::addControlInCurrentFrame(Control *ctrl) +{ + Control *c; + + ctrl->next = 0; + if (frames[loadingFrame].controls == 0) { + frames[loadingFrame].controls = ctrl; + } else { + for(c = frames[loadingFrame].controls; c->next; c = c->next); + c->next = ctrl; + } +} + +void +Program::modifySettings(long flags) +{ + settings = flags; +} + +long +Program::searchFrame(GraphicDevice *gd, char *label, char *target) +{ + long f; + DisplayListEntry *e; + Program *prg; + + // Current movie + if (target[0] == 0) { + for(f=0; f < nbFrames; f++) + { + if (frames[f].label && !strcmp(label,frames[f].label)) { + return f; + } + } + } + + // Kludge !!! + for (e = dl->list; e; e = e->next) { + if (e->character->isSprite()) { + prg = ((Sprite *)e->character)->program; + f = prg->searchFrame(gd,label,""); + if (f >= 0 && f < prg->nbFrames) { + prg->dl->updateBoundingBox(e); + prg->gotoFrame(gd, f); + prg->nextFrame = f; + prg->dl->updateBoundingBox(e); + return -1; + } + } + } + + return -1; +} + +void loadNewSwf(FlashMovie *movie, char *url, int level) +{ + CInputScript *s,*prev,**l; + + if (movie->getSwf == NULL) return; + + for(s = movie->main, prev = 0; s != NULL; prev = s, s = s->next) { + if (s->level == level) { + // Mark movie to be deleted + s->level = -1; + break; + } + } + + //printf("Unload movie @ %d\n", level); + + if (*url == 0) return; // Just UnloadMovie + + s = new CInputScript(level); + if (s == NULL) return; + + /* insert it in the right order */ + l = &movie->main; + while (*l != NULL && (*l)->level < level) l = &(*l)->next; + s->next = *l; + *l = s; + + // Notify the external loader of a new movie to load + movie->getSwf(url, level, movie->getSwfClientData); +} diff --git a/core/multimedia/opieplayer/libflash/program.h b/core/multimedia/opieplayer/libflash/program.h new file mode 100644 index 0000000..7672d88 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/program.h @@ -0,0 +1,185 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _PROGRAM_H_ +#define _PROGRAM_H_ + +enum ControlType { + ctrlPlaceObject, + ctrlPlaceObject2, + ctrlRemoveObject, + ctrlRemoveObject2, + ctrlDoAction, + ctrlStartSound, + ctrlStopSound, + ctrlBackgroundColor +}; + +enum PlaceFlags { + placeIsMove = 0x01, + placeHasCharacter = 0x02, + placeHasMatrix = 0x04, + placeHasColorXform = 0x08, + placeHasRatio = 0x10, + placeHasName = 0x20, + placeHasClip = 0x40 +}; + +struct Control { + ControlType type; + + // Place, Remove, Sound + Character *character; + long depth; + + // Place 1&2 + PlaceFlags flags; + Matrix matrix; + Cxform cxform; + long ratio; + long clipDepth; + char *name; + + // BackgroundColor + Color color; + + // DoAction + ActionRecord *actionRecords; + + struct Control *next; + + + // Methods + + void addActionRecord( ActionRecord *ar) + { + ar->next = 0; + + if (actionRecords == 0) { + actionRecords = ar; + } else { + ActionRecord *current; + + for(current = actionRecords; current->next; current = current->next); + + current->next = ar; + } + }; + + Control() + { + actionRecords = 0; + cxform.aa = 1.0; cxform.ab = 0; + cxform.ra = 1.0; cxform.rb = 0; + cxform.ga = 1.0; cxform.gb = 0; + cxform.ba = 1.0; cxform.bb = 0; + ratio = 0; + clipDepth = 0; + name = 0; + }; + + ~Control() + { + ActionRecord *ar,*del; + for(ar = actionRecords; ar;) + { + del = ar; + ar = ar->next; + delete del; + } + if (name) { + free(name); + } + }; +}; + +struct Frame { + char *label; + Control *controls; // Controls for this frame +}; + +enum MovieStatus { + MoviePaused, + MoviePlay +}; + +struct FlashMovie; + +struct Program { + DisplayList *dl; + + Frame *frames; // Array + long nbFrames; // Number of valid frames + long currentFrame; + long loadingFrame; + long totalFrames; // Total expected number of frames + long nextFrame; + int movieWait; // If true freeze movie until next loaded frame + MovieStatus movieStatus; + Sound *currentSound; + long settings; + FlashMovie *movie; + long render; // True if needed to be rendered + + Program(FlashMovie *movie,long n); + ~Program(); + + void rewindMovie(); + void pauseMovie(); + void continueMovie(); + void nextStepMovie(); + void gotoFrame(GraphicDevice *gd, long f); + + long processMovie(GraphicDevice *, SoundMixer *); + long nestedMovie(GraphicDevice *, SoundMixer *, Matrix *, Cxform *); + long runFrame(GraphicDevice *, SoundMixer *, long f, long action=1); + long handleEvent(GraphicDevice *, SoundMixer *, FlashEvent *); + long doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *); + void setCurrentFrameLabel(char *label); + void advanceFrame(); + void addControlInCurrentFrame(Control *ctrl); + void setGetUrlMethod( void (*)(char *, char *, void *), void *); + void modifySettings(long flags); + long searchFrame(GraphicDevice *gd, char *, char *); + void validateLoadingFrame(); + long getCurrentFrame(); + void setCurrentFrame(long); + + Frame *getFrames(); + long getNbFrames(); + + DisplayList *getDisplayList(); + +#ifdef DUMP + void dump(BitStream *bs); +static void dumpActions(BitStream *bs, ActionRecord *actions); +#endif +}; + +DisplayListEntry *findFocus(DisplayList *dl); +void setFlashTimer(struct timeval *tv, int time_ms); +int checkFlashTimer(struct timeval *tv); + +void loadNewSwf(FlashMovie *movie, char *url, int level); + +void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e); + +long processMovie(FlashMovie *movie); + +#endif /* _PROGRAM_H_ */ diff --git a/core/multimedia/opieplayer/libflash/rect.h b/core/multimedia/opieplayer/libflash/rect.h new file mode 100644 index 0000000..cb84eb3 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/rect.h @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _RECT_H_ +#define _RECT_H_ + +struct Rect +{ + long xmin; + long xmax; + long ymin; + long ymax; + + long getWidth() { + return xmax-xmin; + }; + + long getHeight() { + return ymax-ymin; + }; + + void print() { + printf("Xmin = %d Xmax = %d Ymin = %d Ymax = %d\n", + (int)xmin,(int)xmax,(int)ymin,(int)ymax); + }; + + void reset() { + xmin = LONG_MAX; + ymin = LONG_MAX; + xmax = LONG_MIN; + ymax = LONG_MIN; + }; + +#ifdef DUMP + void dump(BitStream *bs); +#endif +}; + +#endif /* _RECT_H_ */ diff --git a/core/multimedia/opieplayer/libflash/script.cc b/core/multimedia/opieplayer/libflash/script.cc new file mode 100644 index 0000000..db65819 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/script.cc @@ -0,0 +1,1988 @@ +#include "swf.h" + +//////////////////////////////////////////////////////////// +// This file is derived from the 'buggy' SWF parser provided +// by Macromedia. +// +// Modifications : Olivier Debon +// + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define printf(fmt,args...) + +////////////////////////////////////////////////////////////////////// +// Inline input script object methods. +////////////////////////////////////////////////////////////////////// + +// +// Inlines to parse a Flash file. +// +inline U8 CInputScript::GetByte(void) +{ + return m_fileBuf[m_filePos++]; +} + +inline U16 CInputScript::GetWord(void) +{ + U8 * s = m_fileBuf + m_filePos; + m_filePos += 2; + return (U16) s[0] | ((U16) s[1] << 8); +} + +inline U32 CInputScript::GetDWord(void) +{ + U8 * s = m_fileBuf + m_filePos; + m_filePos += 4; + return (U32) s[0] | ((U32) s[1] << 8) | ((U32) s[2] << 16) | ((U32) s [3] << 24); +} + + + + +////////////////////////////////////////////////////////////////////// +// Input script object methods. +////////////////////////////////////////////////////////////////////// + +CInputScript::CInputScript(int level) +// Class constructor. +{ + this->level = level; + + // Initialize the input pointer. + m_fileBuf = NULL; + + // Initialize the file information. + m_filePos = 0; + m_fileSize = 0; + m_fileVersion = 0; + + // Initialize the bit position and buffer. + m_bitPos = 0; + m_bitBuf = 0; + + // Initialize the output file. + m_outputFile = NULL; + + // Set to true if we wish to dump all contents long form + m_dumpAll = false; + + // if set to true will dump image guts (i.e. jpeg, zlib, etc. data) + m_dumpGuts = false; + + needHeader = 1; + program = 0; + + outOfMemory = 0; + + next = NULL; + + return; +} + + +CInputScript::~CInputScript(void) +// Class destructor. +{ + // Free the buffer if it is there. + if (m_fileBuf) + { + delete program; + m_fileBuf = NULL; + m_fileSize = 0; + } +} + + +U16 CInputScript::GetTag(void) +{ + // Save the start of the tag. + m_tagStart = m_filePos; + + if (m_actualSize-m_filePos < 2) return notEnoughData; + + // Get the combined code and length of the tag. + U16 code = GetWord(); + + // The length is encoded in the tag. + U32 len = code & 0x3f; + + // Remove the length from the code. + code = code >> 6; + + // Determine if another long word must be read to get the length. + if (len == 0x3f) { + if (m_actualSize-m_filePos < 4) return notEnoughData; + len = (U32) GetDWord(); + } + + // Determine the end position of the tag. + m_tagEnd = m_filePos + (U32) len; + m_tagLen = (U32) len; + + return code; +} + + +void CInputScript::GetRect (Rect * r) +{ + InitBits(); + int nBits = (int) GetBits(5); + r->xmin = GetSBits(nBits); + r->xmax = GetSBits(nBits); + r->ymin = GetSBits(nBits); + r->ymax = GetSBits(nBits); +} + +void CInputScript::GetMatrix(Matrix* mat) +{ + InitBits(); + + // Scale terms + if (GetBits(1)) + { + int nBits = (int) GetBits(5); + mat->a = (float)(GetSBits(nBits))/(float)0x10000; + mat->d = (float)(GetSBits(nBits))/(float)0x10000; + } + else + { + mat->a = mat->d = 1.0; + } + + // Rotate/skew terms + if (GetBits(1)) + { + int nBits = (int)GetBits(5); + mat->c = (float)(GetSBits(nBits))/(float)0x10000; + mat->b = (float)(GetSBits(nBits))/(float)0x10000; + } + else + { + mat->b = mat->c = 0.0; + } + + // Translate terms + int nBits = (int) GetBits(5); + mat->tx = GetSBits(nBits); + mat->ty = GetSBits(nBits); +} + + +void CInputScript::GetCxform(Cxform* cx, BOOL hasAlpha) +{ + int flags; + int nBits; + float aa; long ab; + float ra; long rb; + float ga; long gb; + float ba; long bb; + + InitBits(); + + flags = (int) GetBits(2); + nBits = (int) GetBits(4); + aa = 1.0; ab = 0; + if (flags & 1) + { + ra = (float) GetSBits(nBits)/256.0; + ga = (float) GetSBits(nBits)/256.0; + ba = (float) GetSBits(nBits)/256.0; + if (hasAlpha) aa = (float) GetSBits(nBits)/256.0; + } + else + { + ra = ga = ba = 1.0; + } + if (flags & 2) + { + rb = (S32) GetSBits(nBits); + gb = (S32) GetSBits(nBits); + bb = (S32) GetSBits(nBits); + if (hasAlpha) ab = (S32) GetSBits(nBits); + } + else + { + rb = gb = bb = 0; + } + if (cx) { + cx->aa = aa; + cx->ab = ab; + cx->ra = ra; + cx->rb = rb; + cx->ga = ga; + cx->gb = gb; + cx->ba = ba; + cx->bb = bb; + } +} + + +/* XXX: should allocate string */ +char *CInputScript::GetString(void) +{ + // Point to the string. + char *str = (char *) &m_fileBuf[m_filePos]; + + // Skip over the string. + while (GetByte()); + + return str; +} + +void CInputScript::InitBits(void) +{ + // Reset the bit position and buffer. + m_bitPos = 0; + m_bitBuf = 0; +} + + +S32 CInputScript::GetSBits (S32 n) +// Get n bits from the string with sign extension. +{ + // Get the number as an unsigned value. + S32 v = (S32) GetBits(n); + + // Is the number negative? + if (v & (1L << (n - 1))) + { + // Yes. Extend the sign. + v |= -1L << n; + } + + return v; +} + + +U32 CInputScript::GetBits (S32 n) +// Get n bits from the stream. +{ + U32 v = 0; + + for (;;) + { + S32 s = n - m_bitPos; + if (s > 0) + { + // Consume the entire buffer + v |= m_bitBuf << s; + n -= m_bitPos; + + // Get the next buffer + m_bitBuf = GetByte(); + m_bitPos = 8; + } + else + { + // Consume a portion of the buffer + v |= m_bitBuf >> -s; + m_bitPos -= n; + m_bitBuf &= 0xff >> (8 - m_bitPos); // mask off the consumed bits + return v; + } + } +} + +void CInputScript::ParseFreeCharacter() +{ + U32 tagid = (U32) GetWord(); + + tagid = tagid; + + printf("tagFreeCharacter \ttagid %-5u\n", tagid); +} + + +void CInputScript::ParsePlaceObject() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlPlaceObject; + ctrl->flags = (PlaceFlags)(placeHasMatrix | placeHasCharacter); + + ctrl->character = getCharacter(GetWord()); + ctrl->depth = GetWord(); + + GetMatrix(&(ctrl->matrix)); + + if ( m_filePos < m_tagEnd ) + { + ctrl->flags = (PlaceFlags)(ctrl->flags | placeHasColorXform); + + GetCxform(&ctrl->cxform, false); + } + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParsePlaceObject2() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlPlaceObject2; + + ctrl->flags = (PlaceFlags)GetByte(); + ctrl->depth = GetWord(); + + // Get the tag if specified. + if (ctrl->flags & placeHasCharacter) + { + ctrl->character = getCharacter(GetWord()); + } + + // Get the matrix if specified. + if (ctrl->flags & placeHasMatrix) + { + GetMatrix(&(ctrl->matrix)); + } + + // Get the color transform if specified. + if (ctrl->flags & placeHasColorXform) + { + GetCxform(&ctrl->cxform, true); + } + + // Get the ratio if specified. + if (ctrl->flags & placeHasRatio) + { + ctrl->ratio = GetWord(); + } + + // Get the ratio if specified. + if (ctrl->flags & placeHasName) + { + ctrl->name = strdup(GetString()); + } + + // Get the clipdepth if specified. + if (ctrl->flags & placeHasClip) + { + ctrl->clipDepth = GetWord(); + } + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseRemoveObject() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlRemoveObject; + ctrl->character = getCharacter(GetWord()); + ctrl->depth = GetWord(); + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseRemoveObject2() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlRemoveObject2; + ctrl->depth = GetWord(); + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseSetBackgroundColor() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlBackgroundColor; + ctrl->color.red = GetByte(); + ctrl->color.green = GetByte(); + ctrl->color.blue = GetByte(); + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseDoAction() +{ + Control *ctrl; + ActionRecord *ar; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlDoAction; + + do { + ar = ParseActionRecord(); + if (ar) { + ctrl->addActionRecord( ar ); + } + if (outOfMemory) { + return; + } + } while (ar); + + program->addControlInCurrentFrame(ctrl); + +} + + +void CInputScript::ParseStartSound() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->character = getCharacter(GetWord()); + ctrl->type = ctrlStartSound; + + program->addControlInCurrentFrame(ctrl); + + if (!m_dumpAll) + return; + + U32 code = GetByte(); + + printf("code %-3u", code); + + if ( code & soundHasInPoint ) + printf(" inpoint %u ", GetDWord()); + if ( code & soundHasOutPoint ) + printf(" oupoint %u", GetDWord()); + if ( code & soundHasLoops ) + printf(" loops %u", GetWord()); + + printf("\n"); + if ( code & soundHasEnvelope ) + { + int points = GetByte(); + + for ( int i = 0; i < points; i++ ) + { + printf("\n"); + printf("mark44 %u", GetDWord()); + printf(" left chanel %u", GetWord()); + printf(" right chanel %u", GetWord()); + printf("\n"); + } + } +} + + +void CInputScript::ParseStopSound() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlStopSound; + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseShapeData(int getAlpha, int getStyles) +{ + int shapeRecord = 0; + + if (getStyles) { + // ShapeWithStyle + ParseFillStyle(getAlpha); + ParseLineStyle(getAlpha); + } + + InitBits(); + m_nFillBits = (U16) GetBits(4); + m_nLineBits = (U16) GetBits(4); + + do { + shapeRecord = ParseShapeRecord(getAlpha); + } while (shapeRecord); +} + +int +CInputScript::ParseShapeRecord(long getAlpha) +{ + // Determine if this is an edge. + BOOL isEdge = (BOOL) GetBits(1); + + if (!isEdge) + { + // Handle a state change + U16 flags = (U16) GetBits(5); + + // Are we at the end? + if (flags == 0) + { + // End of shape + return 0; + } + + // Process a move to. + if (flags & flagsMoveTo) + { + U16 nBits = (U16) GetBits(5); + GetSBits(nBits); + GetSBits(nBits); + } + + // Get new fill info. + if (flags & flagsFill0) + { + GetBits(m_nFillBits); + } + if (flags & flagsFill1) + { + GetBits(m_nFillBits); + } + + // Get new line info + if (flags & flagsLine) + { + GetBits(m_nLineBits); + } + + // Check to get a new set of styles for a new shape layer. + if (flags & flagsNewStyles) + { + // Parse the style. + ParseFillStyle(getAlpha); + ParseLineStyle(getAlpha); + + InitBits(); // Bug ! + + // Reset. + m_nFillBits = (U16) GetBits(4); + m_nLineBits = (U16) GetBits(4); + } + + return flags & flagsEndShape ? 0 : 1; + } + else + { + if (GetBits(1)) + { + // Handle a line + U16 nBits = (U16) GetBits(4) + 2; // nBits is biased by 2 + + // Save the deltas + if (GetBits(1)) + { + // Handle a general line. + GetSBits(nBits); + GetSBits(nBits); + } + else + { + // Handle a vert or horiz line. + GetBits(1); + GetSBits(nBits); + } + } + else + { + // Handle a curve + U16 nBits = (U16) GetBits(4) + 2; // nBits is biased by 2 + + // Get the control + GetSBits(nBits); + GetSBits(nBits); + + // Get the anchor + GetSBits(nBits); + GetSBits(nBits); + } + + return 1; + } +} + + +void CInputScript::ParseFillStyle(long getAlpha) + // +{ + U16 i = 0; + FillType type; + Matrix matrix; + + // Get the number of fills. + U16 nFills = GetByte(); + + // Do we have a larger number? + if (nFills == 255) + { + // Get the larger number. + nFills = GetWord(); + } + + // Get each of the fill style. + for (i = 0; i < nFills; i++) + { + U16 fillStyle = GetByte(); + + type = (FillType) fillStyle; + + printf("fillstyle: type=%d\n",defs[i].type); + if (fillStyle & 0x10) + { + U16 nbGradients; + + type = (FillType) (fillStyle & 0x12); + + // Get the gradient matrix. + GetMatrix(&matrix); + + // Get the number of colors. + nbGradients = GetByte(); + + // Get each of the colors. + for (U16 j = 0; j < nbGradients; j++) + { + GetByte(); + GetByte(); + GetByte(); + GetByte(); + if (getAlpha) { + GetByte(); + } + } + } + else if (fillStyle & 0x40) + { + type = (FillType) (fillStyle & 0x41); + + // Get the bitmapId + GetWord(); + + // Get the bitmap matrix. + GetMatrix(&matrix); + } + else + { + type = (FillType) 0; + + // A solid color + GetByte(); + GetByte(); + GetByte(); + if (getAlpha) { + GetByte(); + } + + printf("fillstyle: %x %x %x %x\n", + defs[i].color.red, + defs[i].color.green, + defs[i].color.blue, + defs[i].color.alpha); + } + } +} + +void CInputScript::ParseLineStyle(long getAlpha) +{ + long i; + + // Get the number of lines. + U16 nLines = GetByte(); + + // Do we have a larger number? + if (nLines == 255) + { + // Get the larger number. + nLines = GetWord(); + } + + // Get each of the line styles. + for (i = 0; i < nLines; i++) + { + GetWord(); + GetByte(); + GetByte(); + GetByte(); + if (getAlpha) { + GetByte(); + } + } +} + + +void CInputScript::ParseDefineShape(int level) +{ + Shape *shape; + Rect rect; + U32 tagid; + + tagid = (U32) GetWord(); + shape = new Shape(tagid,level); + if (shape == NULL) { + outOfMemory = 1; + return; + } + shape->dict = this; + + // Get the frame information. + GetRect(&rect); + + shape->setBoundingBox(rect); + + shape->file_ptr = (unsigned char*)malloc(m_tagEnd-m_filePos); + if (shape->file_ptr == NULL) { + outOfMemory = 1; + delete shape; + return; + } + memcpy((void*)shape->file_ptr,(void*)&m_fileBuf[m_filePos], m_tagEnd-m_filePos); + + shape->getStyles = 1; + shape->getAlpha = (level == 3); + + ParseShapeData(level == 3, 1); + + addCharacter(shape); +} + +void CInputScript::S_DumpImageGuts() +{ +#if 0 + U32 lfCount = 0; + printf("----- dumping image details -----"); + while (m_filePos < m_tagEnd) + { + if ((lfCount % 16) == 0) + { + fprintf(stdout, "\n"); + } + lfCount += 1; + fprintf(stdout, "%02x ", GetByte()); + } + fprintf(stdout, "\n"); +#endif +} + +void CInputScript::ParseDefineBits() +{ + Bitmap *bitmap; + U32 tagid = (U32) GetWord(); + int status; + + bitmap = new Bitmap(tagid,1); + if (bitmap == NULL) { + outOfMemory = 1; + return; + } + + status = bitmap->buildFromJpegAbbreviatedData(&m_fileBuf[m_filePos]); + + if (status < 0) { + fprintf(stderr,"Unable to read JPEG data\n"); + delete bitmap; + return; + } + + addCharacter(bitmap); +} + + +void CInputScript::ParseDefineBitsJPEG2() +{ + Bitmap *bitmap; + U32 tagid = (U32) GetWord(); + int status; + + bitmap = new Bitmap(tagid,2); + if (bitmap == NULL) { + outOfMemory = 1; + return; + } + + status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 0, 0); + + if (status < 0) { + fprintf(stderr,"Unable to read JPEG data\n"); + delete bitmap; + return; + } + + addCharacter(bitmap); +} + +void CInputScript::ParseDefineBitsJPEG3() +{ + Bitmap *bitmap; + U32 tagid = (U32) GetWord(); + int status; + long offset; + + printf("tagDefineBitsJPEG3 \ttagid %-5u\n", tagid); + + bitmap = new Bitmap(tagid,3); + if (bitmap == NULL) { + outOfMemory = 1; + return; + } + + offset = GetDWord(); // Not in the specs !!!! + + status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 1, offset); + if (status < 0) { + fprintf(stderr,"Unable to read JPEG data\n"); + delete bitmap; + return; + } + + addCharacter(bitmap); +} + + +void CInputScript::ParseDefineBitsLossless(int level) +{ + Bitmap *bitmap; + U32 tagid = (U32) GetWord(); + int status; + int tableSize; + + bitmap = new Bitmap(tagid,0); + if (bitmap == NULL) { + outOfMemory = 1; + return; + } + + int format = GetByte(); + int width = GetWord(); + int height = GetWord(); + + tableSize = 0; + + if (format == 3) { + tableSize = GetByte(); + } + + status = bitmap->buildFromZlibData(&m_fileBuf[m_filePos], width, height, format, tableSize, level == 2); + + if (status < 0) { + fprintf(stderr,"Unable to read ZLIB data\n"); + delete bitmap; + return; + } + + addCharacter(bitmap); +} + +void CInputScript::ParseJPEGTables() +{ + Bitmap::readJpegTables(&m_fileBuf[m_filePos]); +} + + +ButtonRecord * CInputScript::ParseButtonRecord(long getCxform) +{ + U16 state; + ButtonRecord *br; + long tagid; + Matrix matrix; + long layer; + Cxform *cxform; + + state = (U16) GetByte(); + + if (state == 0) return 0; + + br = new ButtonRecord; + if (br == NULL) { + outOfMemory = 1; + return 0; + } + + tagid = GetWord(); + layer = GetWord(); + GetMatrix(&matrix); + + if (br) { + br->state = (ButtonState) state; + br->character = getCharacter(tagid); + br->layer = layer; + br->cxform = 0; + br->buttonMatrix = matrix; + } + + if (getCxform) { + cxform = new Cxform; + GetCxform(cxform, true); + if (br) { + br->cxform = cxform; + if (cxform == NULL) { + outOfMemory = 1; + } + } + } + + return br; +} + +ActionRecord * CInputScript::ParseActionRecord() +{ + U8 action; + U16 length = 0; + char *url, *target, *label; + long frameIndex, skipCount; + ActionRecord *ar; + + action = GetByte(); + if (action == 0) return 0; + + ar = new ActionRecord; + if (ar == NULL) { + outOfMemory = 1; + return 0; + } + + ar->action = (Action)action; + + if (action & 0x80) { + length = GetWord(); + } + + switch (action) { + case ActionGotoFrame: + frameIndex = GetWord(); + if (ar) { + ar->frameIndex = frameIndex; + } + break; + case ActionGetURL: + url = GetString(); + target = GetString(); + if (ar) { + ar->url = strdup(url); + ar->target = strdup(target); + } + break; + case ActionWaitForFrame: + frameIndex = GetWord(); + skipCount = GetByte(); + if (ar) { + ar->frameIndex = frameIndex; + ar->skipCount = skipCount; + } + break; + case ActionSetTarget: + target = strdup(GetString()); + if (ar) { + ar->target = target; + } + break; + case ActionGoToLabel: + label = GetString(); + if (ar) { + ar->frameLabel = strdup(label); + } + break; + default: + while (length--) { + GetByte(); + } + break; + } + + return ar; +} + +void CInputScript::ParseDefineButton() +{ + Button *button; + ButtonRecord *buttonRecord; + ActionRecord *actionRecord; + + U32 tagid = (U32) GetWord(); + + button = new Button(tagid); + if (button == NULL) { + outOfMemory = 1; + return; + } + + do { + buttonRecord = ParseButtonRecord(); + if (buttonRecord) { + button->addButtonRecord( buttonRecord ); + } + if (outOfMemory) { + return; + } + } while (buttonRecord); + + do { + actionRecord = ParseActionRecord(); + if (actionRecord) { + button->addActionRecord( actionRecord ); + } + if (outOfMemory) { + return; + } + } while (actionRecord); + + addCharacter(button); +} + + +void CInputScript::ParseDefineButton2() +{ + Button *button; + ButtonRecord *buttonRecord; + ActionRecord *actionRecord; + U16 transition; + U16 offset; + U8 menu; + + U32 tagid = (U32) GetWord(); + + button = new Button(tagid); + + if (button == NULL) { + outOfMemory = 1; + return; + } + + menu = GetByte(); + + offset = GetWord(); + + do { + buttonRecord = ParseButtonRecord(true); + if (buttonRecord) { + button->addButtonRecord( buttonRecord ); + } + if (outOfMemory) { + return; + } + } while (buttonRecord); + + while (offset) { + offset = GetWord(); + + transition = GetWord(); + + do { + actionRecord = ParseActionRecord(); + if (actionRecord) { + button->addActionRecord( actionRecord ); + } + if (outOfMemory) { + return; + } + } while (actionRecord); + + button->addCondition( transition ); + } + + addCharacter(button); +} + + +void CInputScript::ParseDefineFont() +{ + SwfFont *font = 0; + U32 tagid = (U32) GetWord(); + long start; + long nb,n; + long offset; + long *offsetTable = 0; + Shape *shapes = 0; + + font = new SwfFont(tagid); + if (font == NULL) { + outOfMemory = 1; + return; + } + start = m_filePos; + + offset = GetWord(); + nb = offset/2; + offsetTable = new long[nb]; + if (offsetTable == NULL) { + goto memory_error; + } + offsetTable[0] = offset; + + for(n=1; nsetFontShapeTable(shapes,nb); + + delete[] offsetTable; + + addCharacter(font); + return; + +memory_error: + outOfMemory = 1; + if (offsetTable) delete offsetTable; + if (font) delete font; + if (shapes) delete[] shapes; +} + + +void CInputScript::ParseDefineMorphShape() +{ + U32 tagid = (U32) GetWord(); + + tagid = tagid; + printf("tagDefineMorphShape \ttagid %-5u\n", tagid); +} + +void CInputScript::ParseDefineFontInfo() +{ + SwfFont *font; + U32 tagid = (U32) GetWord(); + long nameLen; + char *name; + long n,nb; + FontFlags flags; + long *lut; + + font = (SwfFont *)getCharacter(tagid); + + if (font == NULL) { + outOfMemory = 1; + return; + } + + nameLen = GetByte(); + name = new char[nameLen+1]; + if (name == NULL) { + outOfMemory = 1; + return; + } + for(n=0; n < nameLen; n++) + { + name[n] = GetByte(); + } + name[n]=0; + + font->setFontName(name); + + delete name; + + flags = (FontFlags)GetByte(); + + font->setFontFlags(flags); + + nb = font->getNbGlyphs(); + + lut = new long[nb]; + if (lut == NULL) { + outOfMemory = 1; + delete font; + return; + } + + for(n=0; n < nb; n++) + { + if (flags & fontWideCodes) { + lut[n] = GetWord(); + } else { + lut[n] = GetByte(); + } + } + + font->setFontLookUpTable(lut); +} + + + + + +void CInputScript::ParseDefineFont2() +{ + int n; + U32 tagid = (U32) GetWord(); + FontFlags flags; + char *name; + long nameLen; + long fontGlyphCount; + long *offsetTable = NULL; + Shape *shapes = NULL; + long start; + SwfFont *font; + long *lut = NULL; + + font = new SwfFont(tagid); + if (font == NULL) { + goto memory_error; + } + + flags = (FontFlags)GetWord(); + + font->setFontFlags(flags); + + nameLen = GetByte(); + name = new char[nameLen+1]; + if (name == NULL) { + goto memory_error; + } + for(n=0; n < nameLen; n++) + { + name[n] = GetByte(); + } + name[n]=0; + + font->setFontName(name); + + delete name; + + fontGlyphCount = GetWord(); + + start = m_filePos; + + offsetTable = new long[fontGlyphCount]; + if (offsetTable == NULL) { + goto memory_error; + } + for (n=0; nsetFontShapeTable(shapes,fontGlyphCount); + + lut = new long[fontGlyphCount]; + if (lut == NULL) { + goto memory_error; + } + + for(n=0; n < fontGlyphCount; n++) + { + if (flags & 4) { + lut[n] = GetWord(); + } else { + lut[n] = GetByte(); + } + } + + font->setFontLookUpTable(lut); + + delete offsetTable; + + addCharacter(font); + + // This is an incomplete parsing + return; + +memory_error: + outOfMemory = 1; + if (font) delete font; + if (offsetTable) delete offsetTable; + if (lut) delete lut; + if (shapes) delete[] shapes; +} + +TextRecord * CInputScript::ParseTextRecord(int hasAlpha) +{ + TextRecord *tr; + TextFlags flags; + + flags = (TextFlags) GetByte(); + if (flags == 0) return 0; + + tr = new TextRecord; + if (tr == NULL) { + outOfMemory = 1; + return 0; + } + + tr->flags = flags; + + if (flags & isTextControl) { + if (flags & textHasFont) { + long fontId; + + fontId = GetWord(); + tr->font = (SwfFont *)getCharacter(fontId); + } + if (flags & textHasColor) { + tr->color.red = GetByte(); + tr->color.green = GetByte(); + tr->color.blue = GetByte(); + if (hasAlpha) { + tr->color.alpha = GetByte(); + } else { + tr->color.alpha = ALPHA_OPAQUE; + } + } + if (flags & textHasXOffset) { + tr->xOffset = GetWord(); + } + if (flags & textHasYOffset) { + tr->yOffset = GetWord(); + } + if (flags & textHasFont) { + tr->fontHeight = GetWord(); + } + tr->nbGlyphs = GetByte(); + } else { + tr->flags = (TextFlags)0; + tr->nbGlyphs = (long)flags; + } + + tr->glyphs = new Glyph[ tr->nbGlyphs ]; + if (tr->glyphs == NULL) { + outOfMemory = 1; + delete tr; + return 0; + } + + InitBits(); + for (int g = 0; g < tr->nbGlyphs; g++) + { + tr->glyphs[g].index = GetBits(m_nGlyphBits); + tr->glyphs[g].xAdvance = GetBits(m_nAdvanceBits); + } + + return tr; +} + +void CInputScript::ParseDefineText(int hasAlpha) +{ + Text *text; + TextRecord *textRecord; + Matrix m; + Rect rect; + U32 tagid = (U32) GetWord(); + + text = new Text(tagid); + if (text == NULL) { + outOfMemory = 1; + return; + } + + GetRect(&rect); + text->setTextBoundary(rect); + + GetMatrix(&m); + text->setTextMatrix(m); + + m_nGlyphBits = GetByte(); + m_nAdvanceBits = GetByte(); + + do { + textRecord = ParseTextRecord(hasAlpha); + if (textRecord) { + text->addTextRecord( textRecord ); + } + if (outOfMemory) { + delete text; + return; + } + if (m_filePos >= m_tagEnd) break; + } while (textRecord); + + addCharacter(text); +} + + +void CInputScript::ParseDefineSound() +{ + Sound *sound; + U32 tagid = (U32) GetWord(); + long nbSamples; + long flags; + char *buffer; + + sound = new Sound(tagid); + + flags = GetByte(); + sound->setSoundFlags(flags); + + nbSamples = GetDWord(); + buffer = sound->setNbSamples(nbSamples); + if (buffer == NULL) { + outOfMemory = 1; + delete sound; + return; + } + + if (flags & soundIsADPCMCompressed) { + Adpcm *adpcm; + + adpcm = new Adpcm( &m_fileBuf[m_filePos] , flags & soundIsStereo ); + + adpcm->Decompress((short *)buffer, nbSamples); + + delete adpcm; + } else { + memcpy(buffer, &m_fileBuf[m_filePos], m_tagLen-5); + } + + addCharacter(sound); +} + + +void CInputScript::ParseDefineButtonSound() +{ + U32 tagid = (U32) GetWord(); + Button *button; + + tagid = tagid; + + printf("tagDefineButtonSound \ttagid %-5u\n", tagid); + + button = (Button *)getCharacter(tagid); + + if (button == 0) { + printf(" Couldn't find Button id %d\n", tagid); + return; + } + + // step through for button states + for (int i = 0; i < 4; i++) + { + Sound *sound; + U32 soundTag = GetWord(); + + sound = (Sound *)getCharacter(soundTag); + + if (sound) { + button->setButtonSound(sound,i); + } else if (soundTag) { + printf(" Couldn't find Sound id %d\n", soundTag); + } + + switch (i) + { + case 0: + printf("upState \ttagid %-5u\n", soundTag); + break; + case 1: + printf("overState \ttagid %-5u\n", soundTag); + break; + case 2: + printf("downState \ttagid %-5u\n", soundTag); + break; + } + + if (soundTag) + { + U32 code = GetByte(); + printf("sound code %u", code); + + if ( code & soundHasInPoint ) + printf(" inpoint %u", GetDWord()); + if ( code & soundHasOutPoint ) + printf(" outpoint %u", GetDWord()); + if ( code & soundHasLoops ) + printf(" loops %u", GetWord()); + + printf("\n"); + if ( code & soundHasEnvelope ) + { + int points = GetByte(); + + for ( int p = 0; p < points; p++ ) + { + printf("\n"); + printf("mark44 %u", GetDWord()); + printf(" left chanel %u", GetWord()); + printf(" right chanel %u", GetWord()); + printf("\n"); + } + } + } + if (m_filePos == m_tagEnd) break; + } +} + +void CInputScript::ParseSoundStreamHead() +{ + int mixFormat = GetByte(); + + // The stream settings + int format = GetByte(); + int nSamples = GetWord(); + + mixFormat = mixFormat; + format = format; + nSamples = nSamples; + + printf("tagSoundStreamHead \tmixFrmt %-3u frmt %-3u nSamples %-5u\n", mixFormat, format, nSamples); +} + +void CInputScript::ParseSoundStreamHead2() +{ + int mixFormat = GetByte(); + + // The stream settings + int format = GetByte(); + int nSamples = GetWord(); + + mixFormat = mixFormat; + format = format; + nSamples = nSamples; + + //printf("tagSoundStreamHead2 \tmixFormat %-3u format %-3u nSamples %-5u\n", mixFormat, format, nSamples); +} + +void CInputScript::ParseSoundStreamBlock() +{ + printf("tagSoundStreamBlock\n"); +} + +void CInputScript::ParseDefineButtonCxform() +{ + ButtonRecord *br; + Button *button; + U32 tagid = (U32) GetWord(); + + button = (Button *)getCharacter(tagid); + + for (br = button->getButtonRecords(); br; br = br->next) + { + br->cxform = new Cxform; + GetCxform(br->cxform, false); + } +} + +void CInputScript::ParseNameCharacter() +{ + U32 tagid = (U32) GetWord(); + char *label = strdup(GetString()); + + nameCharacter(tagid, label); +} + + +void CInputScript::ParseFrameLabel() +{ + char *label = strdup(GetString()); + program->setCurrentFrameLabel(label); +} + + +void CInputScript::ParseDefineMouseTarget() +{ + printf("tagDefineMouseTarget\n"); +} + + +void CInputScript::ParseDefineSprite() +{ + Sprite *sprite; + Program *prg; + int status; + + U32 tagid = (U32) GetWord(); + U32 frameCount = (U32) GetWord(); + + if (frameCount == 0) return; + + printf("tagDefineSprite \ttagid %-5u \tframe count %-5u\n", tagid, frameCount); + + sprite = new Sprite(program->movie, tagid, frameCount); + if (sprite == NULL) { + outOfMemory = 1; + return; + } + if (sprite->getProgram() == NULL) { + delete sprite; + outOfMemory = 1; + return; + } + + prg = sprite->getProgram(); + + // Set current program + program = prg; + + ParseTags(&status); + + if (outOfMemory) { + delete sprite; + return; + } + + addCharacter(sprite); +} + + +void CInputScript::ParseUnknown(long code, long len) +{ + printf("Unknown Tag : %d - Length = %d\n", code, len); +} + + +void +CInputScript::ParseTags(int *status) + // Parses the tags within the file. +{ + + // Initialize the end of frame flag. + BOOL atEnd = false; + + // Loop through each tag. + while (!atEnd) + { + U32 here; + + // Get the current tag. + U16 code = GetTag(); + + if (code == notEnoughData) { + m_filePos = m_tagStart; + *status |= FLASH_PARSE_NEED_DATA; + return; + } + + //printf("Code %d, tagLen %8u \n", code, m_tagLen); + + here = m_filePos; + + // Get the tag ending position. + U32 tagEnd = m_tagEnd; + + if (m_tagEnd > m_actualSize) { + m_filePos = m_tagStart; + *status |= FLASH_PARSE_NEED_DATA; + return; + } + + switch (code) + { + case stagProtect: + break; + + case stagEnd: + + // We reached the end of the file. + atEnd = true; + + printf("End of Movie\n"); + + break; + + case stagShowFrame: + + // Validate frame + program->validateLoadingFrame(); + *status |= FLASH_PARSE_WAKEUP; + + break; + + case stagFreeCharacter: + ParseFreeCharacter(); + break; + + case stagPlaceObject: + ParsePlaceObject(); + break; + + case stagPlaceObject2: + ParsePlaceObject2(); + break; + + case stagRemoveObject: + ParseRemoveObject(); + break; + + case stagRemoveObject2: + ParseRemoveObject2(); + break; + + case stagSetBackgroundColor: + ParseSetBackgroundColor(); + break; + + case stagDoAction: + ParseDoAction(); + break; + + case stagStartSound: + ParseStartSound(); + break; + + case stagStopSound: + ParseStopSound(); + break; + + case stagDefineShape: + ParseDefineShape(1); + break; + + case stagDefineShape2: + ParseDefineShape(2); + break; + + case stagDefineShape3: + ParseDefineShape(3); + break; + + case stagDefineBits: + ParseDefineBits(); + break; + + case stagDefineBitsJPEG2: + ParseDefineBitsJPEG2(); + break; + + case stagDefineBitsJPEG3: + ParseDefineBitsJPEG3(); + break; + + case stagDefineBitsLossless: + ParseDefineBitsLossless(1); + break; + + case stagDefineBitsLossless2: + ParseDefineBitsLossless(2); + break; + + case stagJPEGTables: + ParseJPEGTables(); + break; + + case stagDefineButton: + ParseDefineButton(); + break; + + case stagDefineButton2: + ParseDefineButton2(); + break; + + case stagDefineFont: + ParseDefineFont(); + break; + + case stagDefineMorphShape: + ParseDefineMorphShape(); + break; + + case stagDefineFontInfo: + ParseDefineFontInfo(); + break; + + case stagDefineText: + ParseDefineText(0); + break; + + case stagDefineText2: + ParseDefineText(1); + break; + + case stagDefineSound: + ParseDefineSound(); + break; + + case stagDefineButtonSound: + ParseDefineButtonSound(); + break; + + case stagSoundStreamHead: + ParseSoundStreamHead(); + break; + + case stagSoundStreamHead2: + ParseSoundStreamHead2(); + break; + + case stagSoundStreamBlock: + ParseSoundStreamBlock(); + break; + + case stagDefineButtonCxform: + ParseDefineButtonCxform(); + break; + + case stagDefineSprite: + Program *save; + + save = program; + ParseDefineSprite(); + program->rewindMovie(); + program = save; + break; + + case stagNameCharacter: + ParseNameCharacter(); + break; + + case stagFrameLabel: + ParseFrameLabel(); + break; + + case stagDefineFont2: + ParseDefineFont2(); + break; + + default: + ParseUnknown(code, m_tagLen); + break; + } + + //printf("Bytes read = %d\n", m_filePos-here); + + // Increment the past the tag. + m_filePos = tagEnd; + + if (outOfMemory) { + fprintf(stderr,"Flash: Out of memory\n"); + *status |= FLASH_PARSE_OOM; + return; + } + } + + program->validateLoadingFrame(); + *status |= FLASH_PARSE_EOM; +} + +int +CInputScript::ParseData(FlashMovie *movie, char * data, long size) +{ + int status = FLASH_PARSE_ERROR; + + m_fileBuf = (unsigned char *)data; + m_actualSize = size; + + if (needHeader) { + + // Do we have sufficient data to read the header ? + if (size < 21) { + return FLASH_PARSE_NEED_DATA; // No, need more data + } + + needHeader = 0; // Yes + + U8 fileHdr[8]; + + memcpy(fileHdr,data,8); + + // Verify the header and get the file size. + if (fileHdr[0] != 'F' || fileHdr[1] != 'W' || fileHdr[2] != 'S' ) + { + //fprintf(stderr, "Not a Flash File.\n"); + return FLASH_PARSE_ERROR; // Error + } + else + { + // Get the file version. + m_fileVersion = (U16) fileHdr[3]; + } + + // Get the file size. + m_fileSize = (U32) fileHdr[4] + | ((U32) fileHdr[5] << 8) + | ((U32) fileHdr[6] << 16) + | ((U32) fileHdr[7] << 24); + + // Verify the minimum length of a Flash file. + if (m_fileSize < 21) + { + //printf("ERROR: File size is too short\n"); + return FLASH_PARSE_ERROR; // Error + } + + // Set the file position past the header and size information. + m_filePos = 8; + + // Get the frame information. + GetRect(&frameRect); + + frameRate = GetWord() >> 8; + + frameCount = GetWord(); + + program = new Program(movie, frameCount); + + if (program == NULL || program->totalFrames == 0) { + return FLASH_PARSE_ERROR; + } + + status |= FLASH_PARSE_START; + } + + ParseTags(&status); + + return status; +} + + diff --git a/core/multimedia/opieplayer/libflash/script.h b/core/multimedia/opieplayer/libflash/script.h new file mode 100644 index 0000000..a41c47e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/script.h @@ -0,0 +1,144 @@ +#ifndef _SCRIPT_H_ +#define _SCRIPT_H_ + +// SWF file parser. +// +////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// Input script object definition. +////////////////////////////////////////////////////////////////////// + +// An input script object. This object represents a script created from +// an external file that is meant to be inserted into an output script. +struct CInputScript : public Dict +{ + int level; + struct CInputScript *next; + + Program *program; // Current parsed program + + // Memory fences + int outOfMemory; + + //Flash info + long frameRate; + long frameCount; + Rect frameRect; + + // Pointer to file contents buffer. + U8 *m_fileBuf; + + // File state information. + U32 m_filePos; + U32 m_fileSize; + U32 m_actualSize; + U32 m_fileStart; + U16 m_fileVersion; + + int needHeader; + + // Bit Handling + S32 m_bitPos; + U32 m_bitBuf; + + // Tag parsing information. + U32 m_tagStart; + U32 m_tagEnd; + U32 m_tagLen; + + // Parsing information. + S32 m_nFillBits; + S32 m_nLineBits; + S32 m_nGlyphBits; + S32 m_nAdvanceBits; + + // Set to true if we wish to dump all contents long form + U32 m_dumpAll; + + // if set to true will dump image guts (i.e. jpeg, zlib, etc. data) + U32 m_dumpGuts; + + // Handle to output file. + FILE *m_outputFile; + + // Constructor/destructor. + CInputScript(int level = 0); + ~CInputScript(); + + // Tag scanning methods. + U16 GetTag(void); + U8 GetByte(void); + U16 GetWord(void); + U32 GetDWord(void); + void GetRect(Rect *r); + void GetMatrix(Matrix *matrix); + + void GetCxform(Cxform *cxform, BOOL hasAlpha); + char *GetString(void); + + // Routines for reading arbitrary sized bit fields from the stream. + // Always call start bits before gettings bits and do not intermix + // these calls with GetByte, etc... + void InitBits(); + S32 GetSBits(S32 n); + U32 GetBits(S32 n); + + // Tag subcomponent parsing methods + void ParseFillStyle(long getAlpha = 0); + void ParseLineStyle(long getAlpha = 0); + int ParseShapeRecord(long getAlpha = 0); + ButtonRecord * ParseButtonRecord(long getCxform = 0); + ActionRecord * ParseActionRecord(); + TextRecord * ParseTextRecord(int hasAlpha = 0); + void ParseShapeData(int getAlpha, int getStyles); + + // Parsing methods. + void ParseEnd(); // 00: stagEnd + void ParseShowFrame(U32 frame, U32 offset); // 01: stagShowFrame + void ParseDefineShape(int level); // 02: stagDefineShape + void ParseFreeCharacter(); // 03: stagFreeCharacter + void ParsePlaceObject(); // 04: stagPlaceObject + void ParseRemoveObject(); // 05: stagRemoveObject + void ParseDefineBits(); // 06: stagDefineBits + void ParseDefineButton(); //x 07: stagDefineButton + void ParseJPEGTables(); // 08: stagJPEGTables + void ParseSetBackgroundColor(); // 09: stagSetBackgroundColor + void ParseDefineFont(); //x 10: stagDefineFont + void ParseDefineText(int hasAplha); //x 11: stagDefineText 33: stagDefineText2 + void ParseDoAction(); // 12: stagDoAction + void ParseDefineFontInfo(); //x 13: stagDefineFontInfo + void ParseDefineSound(); // 14: stagDefineSound + void ParseStartSound(); // 15: stagStartSound + void ParseStopSound(); // 16: stagStopSound + void ParseDefineButtonSound(); // 17: stagDefineButtonSound + void ParseSoundStreamHead(); // 18: stagSoundStreamHead + void ParseSoundStreamBlock(); // 19: stagSoundStreamBlock + void ParseDefineBitsLossless(int level); // 20: stagDefineBitsLossless 36: stagDefineBitsLossless2 + void ParseDefineBitsJPEG2(); // 21: stagDefineBitsJPEG2 + void ParseDefineButtonCxform(); // 23: stagDefineButtonCxform + void ParseProtect(); // 24: stagProtect + void ParsePlaceObject2(); // 26: stagPlaceObject2 + void ParseRemoveObject2(); // 28: stagRemoveObject2 + void ParseDefineButton2(); //x 34: stagDefineButton2 + void ParseDefineBitsJPEG3(); // 35: stagDefineBitsJPEG3 + void ParseDefineMouseTarget(); // 38: stagDefineMouseTarget + void ParseDefineSprite(); //x 39: stagDefineSprite + void ParseNameCharacter(); // 40: stagNameCharacter + void ParseFrameLabel(); // 43: stagFrameLabel + void ParseSoundStreamHead2(); // 45: stagSoundStreamHead2 + void ParseDefineMorphShape(); //x 46: stagDefineMorphShape + void ParseDefineFont2(); //x 48: stagDefineFont2 + void ParseUnknown(long,long); + + void ParseTags(int *); + int ParseData(FlashMovie *movie, char * data, long size); + void S_DumpImageGuts(); + +#ifdef DUMP + long save(char *filenam); +#endif +}; + + +#endif /* _SCRIPT_H_ */ diff --git a/core/multimedia/opieplayer/libflash/shape.cc b/core/multimedia/opieplayer/libflash/shape.cc new file mode 100644 index 0000000..0d8df93 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/shape.cc @@ -0,0 +1,1205 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +#define ABS(v) ((v) < 0 ? -(v) : (v)) + +static void prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, FillStyleDef *f, long n); + +static void clearStyles(GraphicDevice *gd, FillStyleDef *f, long n); + +static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape, + ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func); + +// Constructor + +Shape::Shape(long id, int level) : Character(ShapeType, id) +{ + defLevel = level; + + defaultFillStyle.type = f_Solid; + defaultFillStyle.color.red = 0; + defaultFillStyle.color.green = 0; + defaultFillStyle.color.blue = 0; + defaultFillStyle.color.alpha = ALPHA_OPAQUE; + + defaultLineStyle.width = 0; + + // This is to force a first update + lastMat.a = 0; + lastMat.d = 0; + shape_size += sizeof(Shape); + shape_nb ++; + + file_ptr = NULL; + getStyles = 0; + getAlpha = 0; +} + +Shape::~Shape() +{ + if (file_ptr) { + free(file_ptr); + } +} + +void +Shape::setBoundingBox(Rect rect) +{ + boundary = rect; +} + +void +Shape::getBoundingBox(Rect *bb, DisplayListEntry *e) +{ + *bb = boundary; +} + +int +Shape::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform) +{ + //printf("TagId = %d\n", getTagId()); + //if (getTagId() != 220) return 0; + + if (cxform) { + defaultFillStyle.color = cxform->getColor(gd->getForegroundColor()); + } else { + defaultFillStyle.color = gd->getForegroundColor(); + } + defaultFillStyle.color.pixel = gd->allocColor(defaultFillStyle.color); + + drawShape(gd, matrix, cxform, this, ShapeDraw, NULL, 0); + return 0; +} + +void +Shape::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func) +{ + gd->setClipping(0); + drawShape(gd,matrix,0,this,ShapeGetRegion,id,scan_line_func); + gd->setClipping(1); +} + +/************************************************************************/ + +/* create a new path */ + +static void newPath(ShapeParser *shape, + long x, long y) +{ + Path *p; + long x1,y1; + + p=&shape->curPath; + + x1 = shape->matrix->getX(x, y); + y1 = shape->matrix->getY(x, y); + + p->lastX = x1; + p->lastY = y1; + + p->nb_edges = 0; + p->nb_segments = 0; +} + + +static void addSegment1(ShapeParser *shape, + long x, long y, + FillStyleDef *f0, + FillStyleDef *f1, + LineStyleDef *l) +{ + Path *p; + p=&shape->curPath; + + if (l) { + /* a line is defined ... it will be drawn later */ + LineSegment *ls; + + ls = new LineSegment; + if (ls != NULL) { + ls->l = l; + ls->x1 = p->lastX; + ls->y1 = p->lastY; + ls->x2 = x; + ls->y2 = y; + ls->first = (p->nb_segments == 0); + ls->next = NULL; + if (shape->last_line == NULL) { + shape->first_line = ls; + } else { + shape->last_line->next = ls; + } + shape->last_line = ls; + } + } + + /* anti antialiasing not needed if line */ + if (!shape->reverse) { + shape->gd->addSegment(p->lastX,p->lastY,x,y,f0,f1,l ? 0 : 1); + } else { + shape->gd->addSegment(p->lastX,p->lastY,x,y,f1,f0,l ? 0 : 1); + } + + p->lastX = x; + p->lastY = y; + + p->nb_segments++; +} + + +static void addLine(ShapeParser *shape, long x, long y, + FillStyleDef *f0, + FillStyleDef *f1, + LineStyleDef *l) +{ + long x1,y1; + Path *p; + + p=&shape->curPath; + + x1 = shape->matrix->getX(x, y); + y1 = shape->matrix->getY(x, y); + + addSegment1(shape,x1,y1,f0,f1,l); + + p->nb_edges++; +} + + +// This is based on Divide and Conquer algorithm. + +#define BFRAC_BITS 0 +#define BFRAC (1 << BFRAC_BITS) + +static void +bezierBuildPoints (ShapeParser *s, + int subdivisions, + long a1X, long a1Y, + long cX, long cY, + long a2X, long a2Y) +{ + long c1X,c1Y; + long c2X,c2Y; + long X,Y; + long xmin,ymin,xmax,ymax; + + if (subdivisions != 0) { + + /* find the bounding box */ + + if (a1X < cX) { + xmin = a1X; + xmax = cX; + } else { + xmin = cX; + xmax = a1X; + } + if (a2X < xmin) xmin = a2X; + if (a2X > xmax) xmax = a2X; + + if (a1Y < cY) { + ymin = a1Y; + ymax = cY; + } else { + ymin = cY; + ymax = a1Y; + } + if (a2Y < ymin) ymin = a2Y; + if (a2Y > ymax) ymax = a2Y; + + if (((xmax - xmin) + (ymax - ymin)) >= (BFRAC*FRAC*2)) { + // Control point 1 + c1X = (a1X+cX) >> 1; + c1Y = (a1Y+cY) >> 1; + + // Control point 2 + c2X = (a2X+cX) >> 1; + c2Y = (a2Y+cY) >> 1; + + // New point + X = (c1X+c2X) >> 1; + Y = (c1Y+c2Y) >> 1; + + subdivisions--; + + bezierBuildPoints(s, subdivisions, + a1X, a1Y, c1X, c1Y, X, Y); + bezierBuildPoints(s, subdivisions, + X, Y, c2X, c2Y, a2X, a2Y); + + return; + } + } + + addSegment1(s, (a2X+(BFRAC/2)) >> BFRAC_BITS, + (a2Y+(BFRAC/2)) >> BFRAC_BITS, s->f0, s->f1, s->l); +} + +/* this code is broken, but useful to get something */ +static void flushPaths(ShapeParser *s) +{ + LineSegment *ls; + LineStyleDef *l; + long nx,ny,nn,w; + GraphicDevice *gd = s->gd; + + /* draw the filled polygon */ + gd->drawPolygon(); + + /* draw the lines */ + ls = s->first_line; + if (ls != NULL) { + do { + l = ls->l; + +#if 0 + printf("line %d %d %d %d width=%d\n", + ls->x1, ls->y1, ls->x2, ls->y2, l->width); +#endif + + /* XXX: this width is false, but it is difficult (and expensive) + to have the correct one */ + w = ABS((long)(s->matrix->a * l->width)); + + if (w <= ((3*FRAC)/2)) { + w = FRAC; + } +#ifdef THIN_LINES + if (w <= ((3*FRAC)/2)) { + // draw the thin lines only in shapeAction == shapeDraw + if (gd->scan_line_func == NULL) { + gd->setForegroundColor(l->fillstyle.color); + gd->drawLine(ls->x1, ls->y1, ls->x2, ls->y2, w); + } + } else { +#else + { +#endif + /* compute the normal vector */ + + nx = -(ls->y2 - ls->y1); + ny = (ls->x2 - ls->x1); + + /* normalize & width */ + nn = 2 * (long) sqrt(nx * nx + ny * ny); + +#define UL ls->x1 + nx -ny, ls->y1 + ny +nx +#define UR ls->x2 + nx +ny, ls->y2 + ny -nx +#define LL ls->x1 - nx -ny, ls->y1 - ny +nx +#define LR ls->x2 - nx +ny, ls->y2 - ny -nx + + if (nn > 0) { + nx = (nx * w) / nn; + ny = (ny * w) / nn; + + /* top segment */ + gd->addSegment(UL, UR, NULL, &l->fillstyle, 1); + + /* bottom segment */ + gd->addSegment(LL, LR, &l->fillstyle, NULL, 1); + + /* right segment */ + gd->addSegment(UR, LR, &l->fillstyle, NULL, 1); + + /* left segment */ + gd->addSegment(UL, LL, NULL, &l->fillstyle, 1); + + /* draw the line polygon */ + gd->drawPolygon(); + } + } + + ls = ls->next; + } while (ls != NULL); + + /* delete the line structures */ + + ls = s->first_line; + while (ls != NULL) { + LineSegment *ls1; + ls1 = ls->next; + delete ls; + ls = ls1; + } + + /* reset the line pointers */ + s->first_line = NULL; + s->last_line = NULL; + } +} + + +static void addBezier(ShapeParser *shape, + long ctrlX1, long ctrlY1, + long newX1, long newY1, + FillStyleDef *f0, + FillStyleDef *f1, + LineStyleDef *l) +{ + long newX,newY,ctrlX,ctrlY; + Path *p; + + p=&shape->curPath; + + /* note: we do the matrix multiplication before calculating the + bezier points (faster !) */ + + ctrlX = shape->matrix->getX(ctrlX1, ctrlY1); + ctrlY = shape->matrix->getY(ctrlX1, ctrlY1); + newX = shape->matrix->getX(newX1, newY1); + newY = shape->matrix->getY(newX1, newY1); + + shape->f0 = f0; + shape->f1 = f1; + shape->l = l; + + bezierBuildPoints(shape, 3, + p->lastX<lastY<nb_edges++; +} + +/***********************************************************************/ + + +/* bit parser */ + +static void InitBitParser(struct BitParser *b,U8 *buf) +{ + b->ptr = buf; +} + +static void InitBits(struct BitParser *b) +{ + // Reset the bit position and buffer. + b->m_bitPos = 0; + b->m_bitBuf = 0; +} + + + +static inline U8 GetByte(struct BitParser *b) +{ + U8 v; + v = *b->ptr++; + return v; +} + +static inline U16 GetWord(struct BitParser *b) +{ + U8 *s; + U16 v; + s = b->ptr; + v = s[0] | ((U16) s[1] << 8); + b->ptr = s + 2; + return v; +} + +static inline U32 GetDWord(struct BitParser *b) +{ + U32 v; + U8 * s = b->ptr; + v = (U32) s[0] | ((U32) s[1] << 8) | + ((U32) s[2] << 16) | ((U32) s [3] << 24); + b->ptr = s + 4; + return v; +} + +static inline U32 GetBit (struct BitParser *b) +{ + U32 v; + S32 m_bitPos = b->m_bitPos; + U32 m_bitBuf = b->m_bitBuf; + + if (m_bitPos == 0) { + m_bitBuf = (U32)(*b->ptr++) << 24; + m_bitPos = 8; + } + + v = (m_bitBuf >> 31); + + m_bitPos--; + m_bitBuf <<= 1; + + b->m_bitPos = m_bitPos; + b->m_bitBuf = m_bitBuf; + + return v; +} + +static inline U32 GetBits (struct BitParser *b, int n) +{ + U32 v; + S32 m_bitPos = b->m_bitPos; + U32 m_bitBuf = b->m_bitBuf; + + if (n == 0) + return 0; + + while (m_bitPos < n) { + m_bitBuf |= (U32)(*b->ptr++) << (24 - m_bitPos); + m_bitPos += 8; + } + + v = m_bitBuf >> (32 - n); + m_bitBuf <<= n; + m_bitPos -= n; + + b->m_bitPos = m_bitPos; + b->m_bitBuf = m_bitBuf; + return v; +} + +// Get n bits from the string with sign extension. +static inline S32 GetSBits (struct BitParser *b,S32 n) +{ + // Get the number as an unsigned value. + S32 v = (S32) GetBits(b,n); + + // Is the number negative? + if (v & (1L << (n - 1))) + { + // Yes. Extend the sign. + v |= -1L << n; + } + + return v; +} + + + +/************************************************************************/ + +static void GetMatrix(BitParser *b, Matrix* mat) +{ + InitBits(b); + + // Scale terms + if (GetBit(b)) + { + int nBits = (int) GetBits(b,5); + mat->a = (float)(GetSBits(b,nBits))/(float)0x10000; + mat->d = (float)(GetSBits(b,nBits))/(float)0x10000; + } + else + { + mat->a = mat->d = 1.0; + } + + // Rotate/skew terms + if (GetBit(b)) + { + int nBits = (int)GetBits(b,5); + mat->c = (float)(GetSBits(b,nBits))/(float)0x10000; + mat->b = (float)(GetSBits(b,nBits))/(float)0x10000; + } + else + { + mat->b = mat->c = 0.0; + } + + // Translate terms + int nBits = (int) GetBits(b,5); + mat->tx = GetSBits(b,nBits); + mat->ty = GetSBits(b,nBits); +} + +static FillStyleDef * ParseFillStyle(ShapeParser *shape, long *n, long getAlpha) +{ + BitParser *b = &shape->bit_parser; + FillStyleDef *defs; + U16 i = 0; + + // Get the number of fills. + U16 nFills = GetByte(b); + + // Do we have a larger number? + if (nFills == 255) + { + // Get the larger number. + nFills = GetWord(b); + } + + *n = nFills; + defs = new FillStyleDef[ nFills ]; + if (defs == NULL) return NULL; + + // Get each of the fill style. + for (i = 0; i < nFills; i++) + { + U16 fillStyle = GetByte(b); + + defs[i].type = (FillType) fillStyle; + + if (fillStyle & 0x10) + { + defs[i].type = (FillType) (fillStyle & 0x12); + + // Get the gradient matrix. + GetMatrix(b,&(defs[i].matrix)); + + // Get the number of colors. + defs[i].gradient.nbGradients = GetByte(b); + + // Get each of the colors. + for (U16 j = 0; j < defs[i].gradient.nbGradients; j++) + { + defs[i].gradient.ratio[j] = GetByte(b); + defs[i].gradient.color[j].red = GetByte(b); + defs[i].gradient.color[j].green = GetByte(b); + defs[i].gradient.color[j].blue = GetByte(b); + if (getAlpha) { + defs[i].gradient.color[j].alpha = GetByte(b); + } else { + defs[i].gradient.color[j].alpha = ALPHA_OPAQUE; + } + } + } + else if (fillStyle & 0x40) + { + defs[i].type = (FillType) (fillStyle & 0x41); + + // Get the bitmapId + defs[i].bitmap = (Bitmap *)shape->dict->getCharacter(GetWord(b)); + // Get the bitmap matrix. + GetMatrix(b,&(defs[i].matrix)); + } + else + { + defs[i].type = (FillType) 0; + + // A solid color + defs[i].color.red = GetByte(b); + defs[i].color.green = GetByte(b); + defs[i].color.blue = GetByte(b); + if (getAlpha) { + defs[i].color.alpha = GetByte(b); + } else { + defs[i].color.alpha = ALPHA_OPAQUE; + } + } + } + + return defs; +} + +static LineStyleDef * ParseLineStyle(ShapeParser *shape, long *n, long getAlpha) +{ + BitParser *b = &shape->bit_parser; + LineStyleDef *defs,*def; + FillStyleDef *f; + long i; + + // Get the number of lines. + U16 nLines = GetByte(b); + + // Do we have a larger number? + if (nLines == 255) + { + // Get the larger number. + nLines = GetWord(b); + } + + *n = nLines; + defs = new LineStyleDef[ nLines ]; + if (defs == NULL) return NULL; + + // Get each of the line styles. + for (i = 0; i < nLines; i++) + { + def=&defs[i]; + def->width = GetWord(b); + def->color.red = GetByte(b); + def->color.green = GetByte(b); + def->color.blue = GetByte(b); + if (getAlpha) { + def->color.alpha = GetByte(b); + } else { + def->color.alpha = ALPHA_OPAQUE; + } + + f=&def->fillstyle; + f->type = f_Solid; + f->color = def->color; + if (shape->cxform) { + f->color = shape->cxform->getColor(f->color); + } + f->color.pixel = shape->gd->allocColor(f->color); + } + + return defs; +} + +/* 0 = end of shape */ +static int ParseShapeRecord(ShapeParser *shape, ShapeRecord *sr, long getAlpha) +{ + BitParser *b = &shape->bit_parser; + + // Determine if this is an edge. + BOOL isEdge = (BOOL) GetBit(b); + + if (!isEdge) + { + // Handle a state change + U16 flags = (U16) GetBits(b,5); + + // Are we at the end? + if (flags == 0) + { + // End of shape + return 0; + } + + sr->type = shapeNonEdge; + sr->flags = (ShapeFlags)flags; + + // Process a move to. + if (flags & flagsMoveTo) + { + U16 nBits = (U16) GetBits(b,5); + sr->x = GetSBits(b,nBits); + sr->y = GetSBits(b,nBits); + } + + // Get new fill info. + if (flags & flagsFill0) + { + sr->fillStyle0 = GetBits(b,shape->m_nFillBits); + } + if (flags & flagsFill1) + { + sr->fillStyle1 = GetBits(b,shape->m_nFillBits); + } + + // Get new line info + if (flags & flagsLine) + { + sr->lineStyle = GetBits(b,shape->m_nLineBits); + } + + // Check to get a new set of styles for a new shape layer. + if (flags & flagsNewStyles) + { + FillStyleDef *fillDefs; + LineStyleDef *lineDefs; + long n; + + // Parse the style. + fillDefs = ParseFillStyle(shape, &n, getAlpha); + if (fillDefs == NULL) return 0; + + sr->newFillStyles = fillDefs; + sr->nbNewFillStyles = n; + + lineDefs = ParseLineStyle(shape, &n, getAlpha); + if (lineDefs == NULL) return 0; + + sr->newLineStyles = lineDefs; + sr->nbNewLineStyles = n; + + InitBits(b); // Bug ! + + // Reset. + shape->m_nFillBits = (U16) GetBits(b,4); + shape->m_nLineBits = (U16) GetBits(b,4); + } + + //if (flags & flagsEndShape) + //printf("\tEnd of shape.\n\n"); + + return flags & flagsEndShape ? 0 : 1; + } + else + { + if (GetBit(b)) + { + sr->type = shapeLine; + + // Handle a line + U16 nBits = (U16) GetBits(b,4) + 2; // nBits is biased by 2 + + // Save the deltas + if (GetBit(b)) + { + // Handle a general line. + sr->dX = GetSBits(b,nBits); + sr->dY = GetSBits(b,nBits); + } + else + { + // Handle a vert or horiz line. + if (GetBit(b)) + { + // Vertical line + sr->dY = GetSBits(b,nBits); + sr->dX = 0; + } + else + { + // Horizontal line + sr->dX = GetSBits(b,nBits); + sr->dY = 0; + } + } + } + else + { + sr->type = shapeCurve; + + // Handle a curve + U16 nBits = (U16) GetBits(b,4) + 2; // nBits is biased by 2 + + // Get the control + sr->ctrlX = GetSBits(b,nBits); + sr->ctrlY = GetSBits(b,nBits); + + // Get the anchor + sr->anchorX = GetSBits(b,nBits); + sr->anchorY = GetSBits(b,nBits); + } + + return 1; + } +} + +static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape, + ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func) +{ + LineStyleDef *l; + FillStyleDef *f0; + FillStyleDef *f1; + ShapeRecord sr1,*sr = &sr1; + int firstPoint; + long lastX,lastY; + LineStyleDef *curLineStyle; + long curNbLineStyles; + FillStyleDef *curFillStyle; + long curNbFillStyles; + StyleList *sl; + ShapeParser sp1,*sp=&sp1; + BitParser *b; + Matrix mat,*matrix; + + mat = (*gd->adjust) * (*matrix1); + matrix = &mat; + + sp->reverse = (mat.a * mat.d) < 0; + + curLineStyle = NULL; + curNbLineStyles = 0; + curFillStyle = NULL; + curNbFillStyles = 0; + sp->style_list = NULL; + + sp->shape = shape; + sp->gd = gd; + sp->matrix = matrix; + sp->cxform = cxform; + sp->dict = shape->dict; + + if (shapeAction == ShapeGetRegion) { + gd->scan_line_func = scan_line_func; + gd->scan_line_func_id = id; + } else { + gd->scan_line_func = NULL; + } + + b = &sp->bit_parser; + InitBitParser(b,shape->file_ptr); + + if (shape->getStyles) { + // ShapeWithStyle + curFillStyle = ParseFillStyle(sp, &curNbFillStyles, shape->getAlpha); + if (curFillStyle == NULL) return; + + curLineStyle = ParseLineStyle(sp, &curNbLineStyles, shape->getAlpha); + if (curLineStyle == NULL) return; + + sl = new StyleList; + if (sl == NULL) return; + + sl->next = NULL; + sl->newFillStyles = curFillStyle; + sl->nbNewFillStyles = curNbFillStyles; + sl->newLineStyles = curLineStyle; + sl->nbNewLineStyles = curNbLineStyles; + + sp->style_list = sl; + + if (shapeAction == ShapeDraw) { + prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles); + } + } + + InitBits(b); + sp->m_nFillBits = (U16) GetBits(b,4); + sp->m_nLineBits = (U16) GetBits(b,4); + + l = 0; + f0 = 0; + f1 = 0; + firstPoint = 1; + lastX = 0; + lastY = 0; + sp->curPath.nb_edges = 0; + sp->first_line = NULL; + sp->last_line = NULL; + + for(;;) { + if (ParseShapeRecord(sp, sr, shape->getAlpha) == 0) break; + + switch (sr->type) + { + case shapeNonEdge: + if (sr->flags & flagsNewStyles) { + + curFillStyle = sr->newFillStyles; + curNbFillStyles = sr->nbNewFillStyles; + curLineStyle = sr->newLineStyles; + curNbLineStyles = sr->nbNewLineStyles; + + sl = new StyleList; + sl->next = sp->style_list; + sl->newFillStyles = sr->newFillStyles; + sl->nbNewFillStyles = sr->nbNewFillStyles; + sl->newLineStyles = sr->newLineStyles; + sl->nbNewLineStyles = sr->nbNewLineStyles; + + sp->style_list = sl; + + if (shapeAction == ShapeDraw) { + prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles); + } + } + if (sr->flags & flagsFill0) { + if (sr->fillStyle0) { + if (curFillStyle) { + f0 = &curFillStyle[sr->fillStyle0-1]; + } else { + f0 = &shape->defaultFillStyle; + } + } else { + f0 = 0; + } + } + if (sr->flags & flagsFill1) { + if (sr->fillStyle1) { + if (curFillStyle) { + f1 = &curFillStyle[sr->fillStyle1-1]; + } else { + f1 = &shape->defaultFillStyle; + } + } else { + f1 = 0; + } + } + if (sr->flags & flagsLine) { + if (sr->lineStyle) { + l = &curLineStyle[sr->lineStyle-1]; + } else { + l = 0; + } + } + if (sr->flags & flagsMoveTo) { + if (sp->curPath.nb_edges == 0) { + /* if no edges, draw the polygon, then the lines */ + flushPaths(sp); + } + + newPath(sp, sr->x, sr->y); + firstPoint = 0; + + lastX = sr->x; + lastY = sr->y; + +#if PRINT + printf("---------\nX,Y = %4d,%4d\n", sr->x/20, sr->y/20); +#endif + } + break; + case shapeCurve: + // Handle Bezier Curves !!! + if (firstPoint) { + newPath(sp, 0, 0); + firstPoint = 0; + } + { + long newX,newY,ctrlX,ctrlY; + + ctrlX = lastX+sr->ctrlX; + ctrlY = lastY+sr->ctrlY; + newX = ctrlX+sr->anchorX; + newY = ctrlY+sr->anchorY; + +#if 1 + addBezier(sp, ctrlX, ctrlY, newX, newY, f0 , f1, l); +#else + addLine(sp, newX, newY, f0, f1, l); +#endif + + lastX = newX; + lastY = newY; + } + break; + case shapeLine: + if (firstPoint) { + newPath(sp, 0, 0); + firstPoint = 0; + } + + lastX += sr->dX; + lastY += sr->dY; + + addLine(sp, lastX, lastY, f0, f1, l); +#if PRINT + printf(" X, Y = %4d,%4d\n", lastX/20, lastY/20); +#endif + break; + } + } + + /* XXX: should test if there is something to draw */ + flushPaths(sp); + + /* free the styles */ + while (sp->style_list) { + StyleList *sl; + + sl=sp->style_list; + sp->style_list = sl->next; + + if (shapeAction == ShapeDraw) { + clearStyles(gd, sl->newFillStyles, sl->nbNewFillStyles); + } + + delete[] sl->newFillStyles; + delete[] sl->newLineStyles; + + delete sl; + } +} + +static void +prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, + FillStyleDef *ftab, long n) +{ + long fs; + FillStyleDef *f; + + for(fs = 0; fs < n; fs++) + { + f = ftab + fs; + switch (f->type) + { + case f_None: + break; + case f_Solid: + if (cxform) { + f->color = cxform->getColor(f->color); + } + f->color.pixel = gd->allocColor(f->color); + break; + case f_LinearGradient: + case f_RadialGradient: + { + Matrix mat; + int n,r,l; + long red, green, blue, alpha; + long dRed, dGreen, dBlue, dAlpha; + long min,max; + Matrix *m; + + mat = *(matrix) * f->matrix; + // Compute inverted matrix + f->gradient.imat = mat.invert(); + + /* renormalize the matrix */ + m=&f->gradient.imat; + if (f->type == f_LinearGradient) { + m->a = m->a * FRAC * (1/128.0) * 65536.0; + m->b = m->b * FRAC * (1/128.0) * 65536.0; + m->tx = (long) ((m->tx + 16384) * (1/128.0) * 65536.0); + } else { + m->a = m->a * FRAC * (1/64.0) * 65536.0; + m->b = m->b * FRAC * (1/64.0) * 65536.0; + m->c = m->c * FRAC * (1/64.0) * 65536.0; + m->d = m->d * FRAC * (1/64.0) * 65536.0; + m->tx = (long) (m->tx * (1/64.0) * 65536.0); + m->ty = (long) (m->ty * (1/64.0) * 65536.0); + } + + // Reset translation in inverted matrix + f->gradient.has_alpha = 0; + + // Build a 256 color ramp + f->gradient.ramp = new Color[256]; + if (f->gradient.ramp == NULL) { + // Invalidate fill style + f->type = f_None; + continue; + } + + // Store min and max + min = f->gradient.ratio[0]; + max = f->gradient.ratio[f->gradient.nbGradients-1]; + for(r=0; r < f->gradient.nbGradients-1; r++) + { + Color start,end; + + l = f->gradient.ratio[r+1]-f->gradient.ratio[r]; + if (l == 0) continue; + + if (cxform) { + start = cxform->getColor(f->gradient.color[r]); + end = cxform->getColor(f->gradient.color[r+1]); + } else { + start = f->gradient.color[r]; + end = f->gradient.color[r+1]; + } + + if (start.alpha != ALPHA_OPAQUE || + end.alpha != ALPHA_OPAQUE) { + f->gradient.has_alpha = 1; + } + + dRed = end.red - start.red; + dGreen = end.green - start.green; + dBlue = end.blue - start.blue; + dAlpha = end.alpha - start.alpha; + + dRed = (dRed<<16)/l; + dGreen = (dGreen<<16)/l; + dBlue = (dBlue<<16)/l; + dAlpha = (dAlpha<<16)/l; + + red = start.red <<16; + green = start.green <<16; + blue = start.blue <<16; + alpha = start.alpha <<16; + + for (n=f->gradient.ratio[r]; n<=f->gradient.ratio[r+1]; n++) { + f->gradient.ramp[n].red = red>>16; + f->gradient.ramp[n].green = green>>16; + f->gradient.ramp[n].blue = blue>>16; + f->gradient.ramp[n].alpha = alpha>>16; + + f->gradient.ramp[n].pixel = gd->allocColor(f->gradient.ramp[n]); + red += dRed; + green += dGreen; + blue += dBlue; + alpha += dAlpha; + } + } + for(n=0; ngradient.ramp[n] = f->gradient.ramp[min]; + } + for(n=max; n<256; n++) { + f->gradient.ramp[n] = f->gradient.ramp[max]; + } + } + break; + case f_TiledBitmap: + case f_clippedBitmap: + if (f->bitmap) { + Matrix *m; + + f->cmap = gd->getColormap(f->bitmap->colormap, + f->bitmap->nbColors, cxform); + if (f->cmap == NULL) { + /* Get the normal cmap anyway */ + f->cmap = f->bitmap->colormap; + } + + f->bitmap_matrix = *(matrix) * f->matrix; + + f->bitmap_matrix = f->bitmap_matrix.invert(); + + m=&f->bitmap_matrix; + m->a = m->a * FRAC * 65536.0; + m->b = m->b * FRAC * 65536.0; + m->c = m->c * FRAC * 65536.0; + m->d = m->d * FRAC * 65536.0; + m->tx = (long) (m->tx * 65536.0); + m->ty = (long) (m->ty * 65536.0); + + f->alpha_table = NULL; + + if (f->bitmap->alpha_buf && cxform) { + unsigned char *alpha_table; + int i; + + alpha_table = (unsigned char *)malloc (256); + if (alpha_table != NULL) { + for(i=0;i<256;i++) { + alpha_table[i] = cxform->getAlpha(i); + } + } + f->alpha_table = alpha_table; + } + } + break; + } + } +} + +static void +clearStyles(GraphicDevice *gd, FillStyleDef *ftab, long n) +{ + long fs; + FillStyleDef *f; + + for(fs = 0; fs < n; fs++) + { + f = ftab + fs; + switch (f->type) + { + case f_Solid: + break; + case f_LinearGradient: + case f_RadialGradient: + if (f->gradient.ramp) { + delete f->gradient.ramp; + } + break; + case f_TiledBitmap: + case f_clippedBitmap: + if (f->bitmap) { + if (f->cmap && f->cmap != f->bitmap->colormap) delete f->cmap; + if (f->alpha_table) free(f->alpha_table); + } + break; + case f_None: + break; + } + } +} + diff --git a/core/multimedia/opieplayer/libflash/shape.h b/core/multimedia/opieplayer/libflash/shape.h new file mode 100644 index 0000000..120ec94 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/shape.h @@ -0,0 +1,181 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _SHAPE_H_ +#define _SHAPE_H_ + +struct LineStyleDef { + long width; + Color color; + FillStyleDef fillstyle; +}; + +enum ShapeRecordType { + shapeNonEdge, + shapeCurve, + shapeLine +}; + +enum ShapeFlags { + flagsMoveTo = 0x01, + flagsFill0 = 0x02, + flagsFill1 = 0x04, + flagsLine = 0x08, + flagsNewStyles = 0x10, + flagsEndShape = 0x80 +}; + +struct ShapeRecord { + ShapeRecordType type; + + // Non Edge + ShapeFlags flags; + long x,y; // Moveto + long fillStyle0; + long fillStyle1; + long lineStyle; + FillStyleDef *newFillStyles; // Array + long nbNewFillStyles; + LineStyleDef *newLineStyles; // Array + long nbNewLineStyles; + + // Curve Edge + long ctrlX, ctrlY; + long anchorX, anchorY; + + // Straight Line + long dX,dY; + + struct ShapeRecord *next; + + ShapeRecord() { + shaperecord_size += sizeof(ShapeRecord); + shaperecord_nb++; + } + +}; + +enum ShapeAction { + ShapeDraw, + ShapeGetRegion +}; + +struct LineSegment { + long x1,y1,x2,y2; + char first; + LineStyleDef *l; + struct LineSegment *next; +}; + +struct Path { + long lastX,lastY; + int nb_edges; + int nb_segments; +}; + +struct StyleList { + FillStyleDef *newFillStyles; // Array + long nbNewFillStyles; + LineStyleDef *newLineStyles; // Array + long nbNewLineStyles; + + StyleList *next; +}; + + +/* fast bit parser */ +struct BitParser { + // Bit Handling + S32 m_bitPos; + U32 m_bitBuf; + + U8 *ptr; +}; + +class Shape; + +/* state of the shape parser */ +struct ShapeParser { + Dict *dict; /* XXX: should be put elsewhere */ + + BitParser bit_parser; + S32 m_nFillBits; + S32 m_nLineBits; + + StyleList *style_list; + Matrix *matrix; + Path curPath; + int reverse; + + /* line rasteriser */ + LineSegment *first_line,*last_line; + GraphicDevice *gd; + Cxform *cxform; + Shape *shape; + + FillStyleDef *f0; + FillStyleDef *f1; + LineStyleDef *l; +}; + +class Shape : public Character { + public: + int defLevel; // 1,2 or 3 + + + Rect boundary; + FillStyleDef defaultFillStyle; + LineStyleDef defaultLineStyle; + + Matrix lastMat; + /* parsing for the rendering stage (saves a lot of memory & + may not reduce significantly the size). These variables + should be in another structure (no state need to be + maintained between two renderings) */ + int getAlpha, getStyles; + unsigned char *file_ptr; + Dict *dict; /* XXX: should be put elsewhere */ + +protected: + void drawLines(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, long, long); + void buildSegmentList(Segment **segs, int height, long &n, Matrix *matrix, int update, int reverse); + Segment *progressSegments(Segment *, long); + Segment *newSegments(Segment *, Segment *); + +public: + Shape(long id = 0 , int level = 1); + ~Shape(); + + void setBoundingBox(Rect rect); + int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform); + void getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func); + + void getBoundingBox(Rect *bb, DisplayListEntry *); + +#ifdef DUMP + void dump(BitStream *bs); + void dumpShapeRecords(BitStream *bs, int alpha); + void dumpFillStyles(BitStream *bs, FillStyleDef *defs, long n, int alpha); + void dumpLineStyles(BitStream *bs, LineStyleDef *defs, long n, int alpha); + void checkBitmaps(BitStream *bs); +#endif +}; + +#endif /* _SHAPE_H_ */ diff --git a/core/multimedia/opieplayer/libflash/sound.cc b/core/multimedia/opieplayer/libflash/sound.cc new file mode 100644 index 0000000..e93f9b5 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sound.cc @@ -0,0 +1,439 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#include +#include +#include +#ifndef NOSOUND +#include +#endif + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +//////////// SOUND + +Sound::Sound(long id) : Character(SoundType, id) +{ + samples = 0; + stereo = 0; + soundRate = 0; + sampleSize = 1; +} + +Sound::~Sound() +{ + if (samples) { + delete samples; + } +} + +void +Sound::setSoundFlags(long f) { + switch (GET_SOUND_RATE_CODE(f)) { + case 0: + soundRate = 5500; + break; + case 1: + soundRate = 11000; + break; + case 2: + soundRate = 22000; + break; + case 3: + soundRate = 44000; + break; + } + if (f & soundIs16bit) { + sampleSize = 2; + } + if (f & soundIsStereo) { + stereo = 1; + } + +#if PRINT + printf("-----\nFlags = %2x\n", f); + printf("Rate = %d kHz ", soundRate); + printf("SampleSize = %d byte(s) ", sampleSize); + if (f & soundIsStereo) { + printf("Stereo "); + } else { + printf("Mono "); + } + if (f & soundIsADPCMCompressed) { + printf("ADPCM\n"); + } else { + printf("Raw\n"); + } +#endif +} + +char * +Sound::setNbSamples(long n) { + long size; + + nbSamples = n; + + size = nbSamples * (stereo ? 2 : 1) * sampleSize; + + samples = new char[ size ]; + + memset((char *)samples,0, size); + + return samples; +} + +long +Sound::getRate() { + return soundRate; +} + +long +Sound::getChannel() { + return stereo ? 2 : 1; +} + +long +Sound::getNbSamples() { + return nbSamples; +} + +long +Sound::getSampleSize() { + return sampleSize; +} + +char * +Sound::getSamples() { + return samples; +} + +//////////// SOUND MIXER + +long SoundMixer::dsp = -1; // Init of descriptor +long SoundMixer::blockSize = 0; // Driver sound buffer size +long SoundMixer::nbInst = 0; // Nb SoundMixer instances +long SoundMixer::sampleSize = 0; +long SoundMixer::stereo = 0; +long SoundMixer::soundRate = 0; +char *SoundMixer::buffer = 0; + +SoundMixer::SoundMixer(char *device) +{ +#ifndef NOSOUND + int status; + long fmt; + + list = 0; // No sound to play + + if (nbInst++) { + // Device is already open + return; + } + + dsp = open(device,O_WRONLY); + if (dsp < 0) { + perror("open dsp"); + return; + } + + // Reset device + status = ioctl(dsp, SNDCTL_DSP_RESET); + if (status < 0) perror("ioctl SNDCTL_DSP_RESET"); + + // Set sample size + fmt = AFMT_S16_LE; + sampleSize = 2; + status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt); + if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT"); + + if (status) { + fmt = AFMT_U8; + sampleSize = 1; + status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt); + if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT"); + } + + // Set stereo channel + stereo = 1; + status = ioctl(dsp, SNDCTL_DSP_STEREO, &stereo); + + if (status) { + stereo = 0; + } + + // Set sound rate in Hertz + soundRate = 11000; + status = ioctl(dsp, SNDCTL_DSP_SPEED, &soundRate); + if (status < 0) perror("ioctl SNDCTL_DSP_SPEED"); + + // Get device buffer size + status = ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &blockSize); + if (status < 0) perror("ioctl SNDCTL_DSP_GETBLKSIZE"); + if (blockSize < 1024) { + blockSize = 32768; + } + blockSize *= 2; + + buffer = (char *)malloc(blockSize); + if (buffer == 0) { + close(dsp); + dsp = -1; + } + +#if PRINT + int caps; + + ioctl(dsp,SNDCTL_DSP_GETCAPS, &caps); + printf("Audio capabilities = %x\n", caps); + printf("Sound Rate = %d\n", soundRate); + printf("Stereo = %d\n", stereo); + printf("Sample Size = %d\n", sampleSize); + printf("Buffer Size = %d\n", blockSize); +#endif /* PRINT */ + +#endif /* NOSOUND */ +} + +SoundMixer::~SoundMixer() +{ + if (--nbInst == 0) { + if (dsp > 0) { + close(dsp); + free(buffer); + } + } +} + +void +SoundMixer::stopSounds() +{ +#ifndef NOSOUND + SoundList *sl,*del; + + for(sl = list; sl; ) { + del = sl; + sl = sl->next; + delete del; + } + list = 0; +#endif +} + +void +SoundMixer::startSound(Sound *sound) +{ +#ifndef NOSOUND + SoundList *sl; + + if (sound) { + // Add sound in list + sl = new SoundList; + sl->rate = sound->getRate(); + sl->stereo = (sound->getChannel() == 2); + sl->sampleSize = sound->getSampleSize(); + sl->current = sound->getSamples(); + sl->remaining = sound->getSampleSize()*sound->getNbSamples()*sound->getChannel(); + sl->next = list; + list = sl; + } +#endif +} + +long +SoundMixer::playSounds() +{ +#ifndef NOSOUND + audio_buf_info bufInfo; + long nbBytes, n; + SoundList *sl,*prev; + int status; + + // Init failed + if (dsp < 0) return 0; + + // No sound to play + if (list == 0) return 0; + + // Get free DMA buffer space + status = ioctl(dsp, SNDCTL_DSP_GETOSPACE, &bufInfo); + + // Free space is not large enough to output data without blocking + // But there are still sounds to play. We must wait. + if (bufInfo.bytes < blockSize) return 1; + + nbBytes = 0; + + // Fill buffer with silence. + memset((void*)buffer, 0, blockSize); + + prev = 0; + sl = list; + while(sl) { + + // Ask sound to fill the buffer + // according to device capabilities + n = fillSoundBuffer(sl, buffer, blockSize); + + // Remember the largest written size + if (n > nbBytes) { + nbBytes = n; + } + + // No more samples for this sound + if (sl->remaining == 0) { + // Remove sound from list + if (prev) { + prev->next = sl->next; + delete sl; + sl = prev->next; + } else { + list = sl->next; + delete sl; + sl = list; + } + } else { + sl = sl->next; + } + } + + if (nbBytes) { + // At last ! Play It ! + write(dsp,buffer,nbBytes); + status = ioctl(dsp, SNDCTL_DSP_POST); + } + + return nbBytes; +#else + return 0; +#endif +} + +long +SoundMixer::fillSoundBuffer(SoundList *sl, char *buff, long buffSize) +{ + long sampleLeft, sampleRight; + long skipOut, skipOutInit; + long skipIn, skipInInit; + long freqRatio; + long totalOut = 0; + + sampleLeft = sampleRight = 0; + skipOutInit = skipInInit = 0; + + freqRatio = sl->rate / soundRate; + if (freqRatio) { + skipOutInit = freqRatio - 1; + skipInInit = 0; + } + + freqRatio = soundRate / sl->rate; + if (freqRatio) { + skipInInit = freqRatio - 1; + skipOutInit = 0; + } + + skipOut = skipOutInit; + skipIn = skipInInit; + while (buffSize && sl->remaining) { + if (skipIn-- == 0) { + // Get sampleLeft + if (sl->sampleSize == 2) { + sampleLeft = (long)(*(short *)(sl->current)); + if (sampleSize == 1) { + sampleLeft = (sampleLeft >> 8) &0xff; + } + } else { + sampleLeft = (long)*(sl->current); + if (sampleSize == 2) { + sampleLeft <<= 8; + } + } + sl->current += sl->sampleSize; + sl->remaining -= sl->sampleSize; + + if (sl->stereo) { + // Get sampleRight + if (sl->sampleSize == 2) { + sampleRight = (long)(*(short *)(sl->current)); + if (sampleSize == 1) { + sampleRight = (sampleRight >> 8) &0xff; + } + } else { + sampleRight = (long)*(sl->current); + if (sampleSize == 2) { + sampleRight <<= 8; + } + } + sl->current += sl->sampleSize; + sl->remaining -= sl->sampleSize; + + } else { + sampleRight = sampleLeft; + } + + skipIn = skipInInit; + } + + if (skipOut-- == 0) { + // Output + if (stereo) { + if (sampleSize == 2) { + *((short *)buff) += sampleLeft/2; + buffSize -= sampleSize; + buff += sampleSize; + *((short *)buff) += sampleRight/2; + buffSize -= sampleSize; + buff += sampleSize; + } else { + *((char *)buff) += sampleLeft/2; + buffSize -= sampleSize; + buff += sampleSize; + *((char *)buff) += sampleRight/2; + buffSize -= sampleSize; + buff += sampleSize; + } + totalOut += 2*sampleSize; + } else { + if (sampleSize == 2) { + *((short *)buff) += (sampleLeft+sampleRight)>>2; + buffSize -= sampleSize; + buff += sampleSize; + } else { + *((char *)buff) += (sampleLeft+sampleRight)>>2; + buffSize -= sampleSize; + buff += sampleSize; + } + totalOut += sampleSize; + } + + skipOut = skipOutInit; + } + } + + return totalOut; +} diff --git a/core/multimedia/opieplayer/libflash/sound.h b/core/multimedia/opieplayer/libflash/sound.h new file mode 100644 index 0000000..c53773d --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sound.h @@ -0,0 +1,83 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _SOUND_H_ +#define _SOUND_H_ + +#define GET_SOUND_RATE_CODE(f) (((f)&0x0c)>>2) + +class Sound : public Character { + long soundRate; // In hz + long stereo; // True if stereo sound + long sampleSize; // 1 or 2 bytes + + char *samples; // Array of samples + long nbSamples; + +public: + Sound(long id); + ~Sound(); + void setSoundFlags(long f); + char *setNbSamples(long n); + + long getRate(); + long getChannel(); + long getNbSamples(); + long getSampleSize(); + char *getSamples(); +}; + +struct SoundList { + long rate; + long stereo; + long sampleSize; + long nbSamples; + long remaining; + char *current; + + SoundList *next; +}; + +class SoundMixer { + + SoundList *list; + +// Class variables +static long dsp; // Descriptor for /dev/dsp +static char * buffer; // DMA buffer +static long blockSize; +static long nbInst; // Number of instances + + // Sound Device Capabilities +static long soundRate; // In hz +static long stereo; // True if stereo sound +static long sampleSize; // 1 or 2 bytes + +public: + SoundMixer(char*); + ~SoundMixer(); + + void startSound(Sound *sound); // Register a sound to be played + void stopSounds(); // Stop every current sounds in the instance + + long playSounds(); // Actually play sounds of all instances + long fillSoundBuffer(SoundList *, char *buffer, long bufferSize); // Fill sound buffer +}; + +#endif /* _SOUND_H_ */ diff --git a/core/multimedia/opieplayer/libflash/sprite.cc b/core/multimedia/opieplayer/libflash/sprite.cc new file mode 100644 index 0000000..de53095 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sprite.cc @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +Sprite::Sprite(FlashMovie *movie, long id, long frameCount) : Character(SpriteType, id) +{ + program = new Program(movie, frameCount); + if (program == NULL) return; + if (program->totalFrames == 0) { + delete program; + program = NULL; + return; + } + program->dl->isSprite = 1; +} + +Sprite::~Sprite() +{ + delete program; +} + +void +Sprite::reset() +{ + program->rewindMovie(); +} + +int +Sprite::isSprite(void) +{ + return 1; +} + +Program * +Sprite::getProgram() +{ + return program; +} + +int +Sprite::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform) +{ + return program->dl->render(gd,matrix,cxform); +} + +ActionRecord * +Sprite::eventHandler(GraphicDevice *gd, FlashEvent *event) +{ +#if 0 + DisplayList *dl; + ActionRecord *actions; + + dl = program->getDisplayList(); + actions = dl->processEvent(gd, event); + if (actions) { + program->doAction(actions,0); + } + return actions; +#endif + return NULL; +} + +void +Sprite::getBoundingBox(Rect *bb, DisplayListEntry *e) +{ + program->dl->getBoundary(bb); +} diff --git a/core/multimedia/opieplayer/libflash/sprite.h b/core/multimedia/opieplayer/libflash/sprite.h new file mode 100644 index 0000000..2ea64bc --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sprite.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _SPRITE_H_ +#define _SPRITE_H_ + +class Sprite : public Character { +public: + Program *program; + + Sprite(FlashMovie *movie, long id, long frameCount); + ~Sprite(); + Program *getProgram(); + int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform); + int hasEventHandler(); + void reset(); + ActionRecord *eventHandler(GraphicDevice *, FlashEvent *); + int isSprite(void); + void getBoundingBox(Rect *bb, DisplayListEntry *de); +}; + +#endif /* _SPRITE_H_ */ diff --git a/core/multimedia/opieplayer/libflash/sqrt.cc b/core/multimedia/opieplayer/libflash/sqrt.cc new file mode 100644 index 0000000..0d8295e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sqrt.cc @@ -0,0 +1,4099 @@ +unsigned char SQRT[] = { + +0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3, +4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5, +5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6, +6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, +9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10, +10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11, +11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, +12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13, +13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, +13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14, +14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, +14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, +17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, +17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, +20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, +20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21, +21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, +21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, +21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22, +22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, +22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, +22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, +23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, +23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, +24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, +24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, +24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, +24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, +25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, +25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, +25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26, +26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, +26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, +26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27, +27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27, +27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27, +27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27, +28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, +28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, +28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, +28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29, +29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, +29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, +29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, +29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31, +31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31, +31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31, +31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33, +33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33, +33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33, +33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33, +33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34, +34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34, +34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34, +34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34, +34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, +36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, +36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, +36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, +36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37, +37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, +37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, +37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, +37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, +37,37,37,37,38,38,38,38,38,38,38,38,38,38,38,38, +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, +38,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 +}; diff --git a/core/multimedia/opieplayer/libflash/swf.h b/core/multimedia/opieplayer/libflash/swf.h new file mode 100644 index 0000000..5f5e4f7 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/swf.h @@ -0,0 +1,229 @@ +#ifndef _SWF_H_ +#define _SWF_H_ + +#include +#include +#include +#include +#include +#include + +#ifdef DUMP +#include "bitstream.h" +#endif + +#include "flash.h" + +extern int debug; + +// Global Types +typedef unsigned long U32, *P_U32, **PP_U32; +typedef signed long S32, *P_S32, **PP_S32; +typedef unsigned short U16, *P_U16, **PP_U16; +typedef signed short S16, *P_S16, **PP_S16; +typedef unsigned char U8, *P_U8, **PP_U8; +typedef signed char S8, *P_S8, **PP_S8; +typedef signed long SFIXED, *P_SFIXED; +typedef signed long SCOORD, *P_SCOORD; +typedef unsigned long BOOL; + +#define ZOOM(v,f) ((v)/(f)) + +#include "matrix.h" +#include "cxform.h" +#include "rect.h" + +#include +#define ST struct timeval t1,t2; +#define START gettimeofday(&t1,0) +#define STOP(msg) gettimeofday(&t2,0); printf("%s Delta = %d ms\n", msg, (t2.tv_sec-t1.tv_sec)*1000+(t2.tv_usec-t1.tv_usec)/1000); fflush(stdout); + +// Start Sound Flags +enum { + soundHasInPoint = 0x01, + soundHasOutPoint = 0x02, + soundHasLoops = 0x04, + soundHasEnvelope = 0x08 + + // the upper 4 bits are reserved for synchronization flags +}; + +// Flags for Sound Format +enum SounfFlags { + soundIsStereo = 0x01, + soundIs16bit = 0x02, + soundIsADPCMCompressed = 0x10 +}; + +// Flags for defining Button States +enum ButtonState { + stateHitTest = 0x08, + stateDown = 0x04, + stateOver = 0x02, + stateUp = 0x01 +}; + +// Actions +enum Action { + // Internal actions + ActionRefresh = 0x00, + ActionPlaySound = 0x01, + // Normal actions + ActionGotoFrame = 0x81, + ActionGetURL = 0x83, + ActionNextFrame = 0x04, + ActionPrevFrame = 0x05, + ActionPlay = 0x06, + ActionStop = 0x07, + ActionToggleQuality = 0x08, + ActionStopSounds = 0x09, + ActionWaitForFrame = 0x8a, + ActionSetTarget = 0x8b, + ActionGoToLabel = 0x8c +}; + +class Sound; + +struct ActionRecord { + Action action; + + // GotoFrame & WaitForFrame + long frameIndex; + + // GetURL + char *url; + char *target; + + // GotoLabel + char *frameLabel; + + // WaitForFrame + long skipCount; + + // Sound + Sound *sound; + + struct ActionRecord *next; + + ActionRecord() { + frameLabel = 0; + url = 0; + target = 0; + sound = 0; + }; + + ~ActionRecord() { + if (frameLabel) free(frameLabel); + if (url) free(url); + if (target) free(target); + }; +}; + +enum FontFlags { + fontUnicode = 0x20, + fontShiftJIS = 0x10, + fontANSI = 0x08, + fontItalic = 0x04, + fontBold = 0x02, + fontWideCodes = 0x01 +}; + +enum TextFlags { + isTextControl = 0x80, + + textIsLarge = 0x70, + textHasFont = 0x08, + textHasColor = 0x04, + textHasYOffset= 0x02, + textHasXOffset= 0x01 +}; + +#ifndef NULL +#define NULL 0 +#endif + +// Tag values that represent actions or data in a Flash script. +enum +{ + stagEnd = 0, + stagShowFrame = 1, + stagDefineShape = 2, + stagFreeCharacter = 3, + stagPlaceObject = 4, + stagRemoveObject = 5, + stagDefineBits = 6, + stagDefineButton = 7, + stagJPEGTables = 8, + stagSetBackgroundColor = 9, + stagDefineFont = 10, + stagDefineText = 11, + stagDoAction = 12, + stagDefineFontInfo = 13, + stagDefineSound = 14, // Event sound tags. + stagStartSound = 15, + stagStopSound = 16, + stagDefineButtonSound = 17, + stagSoundStreamHead = 18, + stagSoundStreamBlock = 19, + stagDefineBitsLossless = 20, // A bitmap using lossless zlib compression. + stagDefineBitsJPEG2 = 21, // A bitmap using an internal JPEG compression table. + stagDefineShape2 = 22, + stagDefineButtonCxform = 23, + stagProtect = 24, // This file should not be importable for editing. + + // These are the new tags for Flash 3. + stagPlaceObject2 = 26, // The new style place w/ alpha color transform and name. + stagRemoveObject2 = 28, // A more compact remove object that omits the character tag (just depth). + stagDefineShape3 = 32, // A shape V3 includes alpha values. + stagDefineText2 = 33, // A text V2 includes alpha values. + stagDefineButton2 = 34, // A button V2 includes color transform, alpha and multiple actions + stagDefineBitsJPEG3 = 35, // A JPEG bitmap with alpha info. + stagDefineBitsLossless2 = 36, // A lossless bitmap with alpha info. + stagDefineSprite = 39, // Define a sequence of tags that describe the behavior of a sprite. + stagNameCharacter = 40, // Name a character definition, character id and a string, (used for buttons, bitmaps, sprites and sounds). + stagFrameLabel = 43, // A string label for the current frame. + stagSoundStreamHead2 = 45, // For lossless streaming sound, should not have needed this... + stagDefineMorphShape = 46, // A morph shape definition + stagDefineFont2 = 48, + + notEnoughData = 0xffff, // Special code +}; + +#ifndef false +#define false 0 +#endif +#ifndef true +#define true 1 +#endif + +extern int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb; + +typedef void (*ScanLineFunc)(void *id, long y, long start, long end); + +class Bitmap; +struct FlashMovie; + +extern "C" { +#include "jpeglib.h" +}; +extern "C" { +//#include "zlib.h" +#include "../src/3rdparty/zlib/zlib.h" +}; + +#include "graphic.h" +#include "character.h" +#include "bitmap.h" +#include "shape.h" +#include "displaylist.h" +#include "sound.h" +#include "button.h" +#include "font.h" +#include "text.h" +#include "adpcm.h" +#include "program.h" +#include "sprite.h" +#include "script.h" +#include "movie.h" + +#endif /* _SWF_H_ */ diff --git a/core/multimedia/opieplayer/libflash/text.cc b/core/multimedia/opieplayer/libflash/text.cc new file mode 100644 index 0000000..1b6cb5e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/text.cc @@ -0,0 +1,246 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +Text::Text(long id) : Character(TextType, id) +{ + textRecords = 0; +} + +Text::~Text() +{ + TextRecord *cur,*del; + + for(cur = textRecords; cur;) + { + del = cur; + cur = cur->next; + delete del; + } +} + +void +Text::setTextBoundary(Rect rect) +{ + boundary = rect; +} + +void +Text::setTextMatrix(Matrix m) +{ + textMatrix = m; +} + +void +Text::addTextRecord(TextRecord *tr) +{ + SwfFont *font = 0; + long n; + + tr->next = 0; + + if (textRecords == 0) { + textRecords = tr; + font = tr->font; + } else { + TextRecord *current; + long fontHeight = 0; + + for(current = textRecords; current->next; current = current->next) { + if (current->flags & textHasFont) { + font = current->font; + fontHeight = current->fontHeight; + } + } + + current->next = tr; + if (current->flags & textHasFont) { + font = current->font; + fontHeight = current->fontHeight; + } + + if (tr->flags & textHasFont) { + font = tr->font; + } else { + tr->font = font; + tr->fontHeight = fontHeight; + } + } + + if (tr->nbGlyphs) { + for(n=0; n < tr->nbGlyphs; n++) { + tr->glyphs[n].code = font->getGlyphCode(tr->glyphs[n].index); + } + } +} + +int +Text::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform) +{ + return doText(gd, matrix, cxform, ShapeDraw, NULL, NULL); +} + +void +Text::getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func) +{ + doText(gd, matrix, 0, ShapeGetRegion, id, scan_line_func); +} + +void +Text::getBoundingBox(Rect *bb, DisplayListEntry *e) +{ + *bb = boundary; +} + +TextRecord * +Text::getTextRecords() +{ + return textRecords; +} + +int +Text::doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action, + void *id, ScanLineFunc scan_line_func) +{ + TextRecord *tr; + long x,y; // Current position + SwfFont *font = 0; // Current font + long fontHeight; + Matrix tmat,fmat; + long g; + + x = y = 0; + fontHeight = 0; + + // Compute final text matrix + tmat = (*matrix) * textMatrix; + + for(tr = textRecords; tr; tr = tr ->next) + { + if (tr->flags & isTextControl) { + if (tr->flags & textHasXOffset) { + x = tr->xOffset; + } + if (tr->flags & textHasYOffset) { + y = tr->yOffset; + } + if (tr->flags & textHasColor) { + if (action == ShapeDraw) { + if (cxform) { + gd->setForegroundColor(cxform->getColor(tr->color)); + } else { + gd->setForegroundColor(tr->color); + } + } + } + } + + font = tr->font; + fontHeight = tr->fontHeight; + // Update font matrix + fmat.a = fontHeight/1000.0; + fmat.d = fontHeight/1000.0; + + assert(font != 0); + for (g = 0; g < tr->nbGlyphs; g++) + { + Shape *shape; + Matrix cmat; + + shape = font->getGlyph( tr->glyphs[g].index ); + +#ifdef PRINT + printf("%c", font->getGlyphCode(tr->glyphs[g].index)); +#endif + + // Update font matrix + fmat.tx = x; + fmat.ty = y; + + // Compute Character matrix + cmat = tmat * fmat; + + if (action == ShapeDraw) { + shape->execute(gd, &cmat, cxform); + } else { + shape->getRegion(gd, &cmat, id, scan_line_func); + } + + // Advance + x += tr->glyphs[g].xAdvance; + } +#ifdef PRINT + printf("\n"); +#endif + } + + if (gd->showMore) { + tmat = (*gd->adjust) * (*matrix); + + long x1,x2,y1,y2; + + x1 = boundary.xmin; + y1 = boundary.ymin; + x2 = boundary.xmax; + y2 = boundary.ymax; + gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),FRAC); + gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),FRAC); + gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),FRAC); + gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),FRAC); + } + + return 0; +} + +////////// TextRecord Methods +TextRecord::TextRecord() { + flags = (TextFlags)0; + font = 0; + fontHeight = 0; + nbGlyphs = 0; + glyphs = 0; + xOffset = 0; + yOffset = 0; +} + +TextRecord::~TextRecord() { + if (nbGlyphs) delete glyphs; +} + +char * +TextRecord::getText() { + static char text[256]; + long g; + + for(g=0; g < nbGlyphs; g++) { + text[g] = glyphs[g].code; + } + text[g] = 0; + + return text; +} diff --git a/core/multimedia/opieplayer/libflash/text.h b/core/multimedia/opieplayer/libflash/text.h new file mode 100644 index 0000000..1ba7b74 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/text.h @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _TEXT_H_ +#define _TEXT_H_ + +struct Glyph { + long index; + long xAdvance; + long code; // Ascii code +}; + +struct TextRecord { + + // Normal text record + Glyph *glyphs; + long nbGlyphs; + + // Control text record + TextFlags flags; + SwfFont *font; + long fontHeight; + Color color; + long xOffset; + long yOffset; + + TextRecord *next; + + TextRecord(); + ~TextRecord(); + + char *getText(); +}; + +class Text : public Character { + + Rect boundary; + Matrix textMatrix; + TextRecord *textRecords; // List + +public: + Text(long id); + ~Text(); + + void setTextBoundary(Rect rect); + void setTextMatrix(Matrix m); + void addTextRecord(TextRecord *tr); + int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform); + void getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func); + int doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action, + void *id, ScanLineFunc scan_line_func); + void getBoundingBox(Rect *bb, DisplayListEntry *e); + TextRecord *getTextRecords(); + +#ifdef DUMP + void dump(BitStream *bs); +#endif +}; + +#endif /* _TEXT_H_ */ diff --git a/core/multimedia/opieplayer/libmad/.cvsignore b/core/multimedia/opieplayer/libmad/.cvsignore new file mode 100644 index 0000000..6fe2396 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/.cvsignore @@ -0,0 +1,2 @@ +moc_* +Makefile diff --git a/core/multimedia/opieplayer/libmad/D.dat b/core/multimedia/opieplayer/libmad/D.dat new file mode 100644 index 0000000..f33d30c --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/D.dat @@ -0,0 +1,607 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +/* + * These are the coefficients for the subband synthesis window. This is a + * reordered version of Table B.3 from ISO/IEC 11172-3. + * + * Every value is parameterized so that shift optimizations can be made at + * compile-time. For example, every value can be right-shifted 12 bits to + * minimize multiply instruction times without any loss of accuracy. + */ + + { PRESHIFT(0x00000000) /* 0.000000000 */, /* 0 */ + -PRESHIFT(0x0001d000) /* -0.000442505 */, + PRESHIFT(0x000d5000) /* 0.003250122 */, + -PRESHIFT(0x001cb000) /* -0.007003784 */, + PRESHIFT(0x007f5000) /* 0.031082153 */, + -PRESHIFT(0x01421000) /* -0.078628540 */, + PRESHIFT(0x019ae000) /* 0.100311279 */, + -PRESHIFT(0x09271000) /* -0.572036743 */, + PRESHIFT(0x1251e000) /* 1.144989014 */, + PRESHIFT(0x09271000) /* 0.572036743 */, + PRESHIFT(0x019ae000) /* 0.100311279 */, + PRESHIFT(0x01421000) /* 0.078628540 */, + PRESHIFT(0x007f5000) /* 0.031082153 */, + PRESHIFT(0x001cb000) /* 0.007003784 */, + PRESHIFT(0x000d5000) /* 0.003250122 */, + PRESHIFT(0x0001d000) /* 0.000442505 */, + + PRESHIFT(0x00000000) /* 0.000000000 */, + -PRESHIFT(0x0001d000) /* -0.000442505 */, + PRESHIFT(0x000d5000) /* 0.003250122 */, + -PRESHIFT(0x001cb000) /* -0.007003784 */, + PRESHIFT(0x007f5000) /* 0.031082153 */, + -PRESHIFT(0x01421000) /* -0.078628540 */, + PRESHIFT(0x019ae000) /* 0.100311279 */, + -PRESHIFT(0x09271000) /* -0.572036743 */, + PRESHIFT(0x1251e000) /* 1.144989014 */, + PRESHIFT(0x09271000) /* 0.572036743 */, + PRESHIFT(0x019ae000) /* 0.100311279 */, + PRESHIFT(0x01421000) /* 0.078628540 */, + PRESHIFT(0x007f5000) /* 0.031082153 */, + PRESHIFT(0x001cb000) /* 0.007003784 */, + PRESHIFT(0x000d5000) /* 0.003250122 */, + PRESHIFT(0x0001d000) /* 0.000442505 */ }, + + { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 1 */ + -PRESHIFT(0x0001f000) /* -0.000473022 */, + PRESHIFT(0x000da000) /* 0.003326416 */, + -PRESHIFT(0x00207000) /* -0.007919312 */, + PRESHIFT(0x007d0000) /* 0.030517578 */, + -PRESHIFT(0x0158d000) /* -0.084182739 */, + PRESHIFT(0x01747000) /* 0.090927124 */, + -PRESHIFT(0x099a8000) /* -0.600219727 */, + PRESHIFT(0x124f0000) /* 1.144287109 */, + PRESHIFT(0x08b38000) /* 0.543823242 */, + PRESHIFT(0x01bde000) /* 0.108856201 */, + PRESHIFT(0x012b4000) /* 0.073059082 */, + PRESHIFT(0x0080f000) /* 0.031478882 */, + PRESHIFT(0x00191000) /* 0.006118774 */, + PRESHIFT(0x000d0000) /* 0.003173828 */, + PRESHIFT(0x0001a000) /* 0.000396729 */, + + -PRESHIFT(0x00001000) /* -0.000015259 */, + -PRESHIFT(0x0001f000) /* -0.000473022 */, + PRESHIFT(0x000da000) /* 0.003326416 */, + -PRESHIFT(0x00207000) /* -0.007919312 */, + PRESHIFT(0x007d0000) /* 0.030517578 */, + -PRESHIFT(0x0158d000) /* -0.084182739 */, + PRESHIFT(0x01747000) /* 0.090927124 */, + -PRESHIFT(0x099a8000) /* -0.600219727 */, + PRESHIFT(0x124f0000) /* 1.144287109 */, + PRESHIFT(0x08b38000) /* 0.543823242 */, + PRESHIFT(0x01bde000) /* 0.108856201 */, + PRESHIFT(0x012b4000) /* 0.073059082 */, + PRESHIFT(0x0080f000) /* 0.031478882 */, + PRESHIFT(0x00191000) /* 0.006118774 */, + PRESHIFT(0x000d0000) /* 0.003173828 */, + PRESHIFT(0x0001a000) /* 0.000396729 */ }, + + { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 2 */ + -PRESHIFT(0x00023000) /* -0.000534058 */, + PRESHIFT(0x000de000) /* 0.003387451 */, + -PRESHIFT(0x00245000) /* -0.008865356 */, + PRESHIFT(0x007a0000) /* 0.029785156 */, + -PRESHIFT(0x016f7000) /* -0.089706421 */, + PRESHIFT(0x014a8000) /* 0.080688477 */, + -PRESHIFT(0x0a0d8000) /* -0.628295898 */, + PRESHIFT(0x12468000) /* 1.142211914 */, + PRESHIFT(0x083ff000) /* 0.515609741 */, + PRESHIFT(0x01dd8000) /* 0.116577148 */, + PRESHIFT(0x01149000) /* 0.067520142 */, + PRESHIFT(0x00820000) /* 0.031738281 */, + PRESHIFT(0x0015b000) /* 0.005294800 */, + PRESHIFT(0x000ca000) /* 0.003082275 */, + PRESHIFT(0x00018000) /* 0.000366211 */, + + -PRESHIFT(0x00001000) /* -0.000015259 */, + -PRESHIFT(0x00023000) /* -0.000534058 */, + PRESHIFT(0x000de000) /* 0.003387451 */, + -PRESHIFT(0x00245000) /* -0.008865356 */, + PRESHIFT(0x007a0000) /* 0.029785156 */, + -PRESHIFT(0x016f7000) /* -0.089706421 */, + PRESHIFT(0x014a8000) /* 0.080688477 */, + -PRESHIFT(0x0a0d8000) /* -0.628295898 */, + PRESHIFT(0x12468000) /* 1.142211914 */, + PRESHIFT(0x083ff000) /* 0.515609741 */, + PRESHIFT(0x01dd8000) /* 0.116577148 */, + PRESHIFT(0x01149000) /* 0.067520142 */, + PRESHIFT(0x00820000) /* 0.031738281 */, + PRESHIFT(0x0015b000) /* 0.005294800 */, + PRESHIFT(0x000ca000) /* 0.003082275 */, + PRESHIFT(0x00018000) /* 0.000366211 */ }, + + { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 3 */ + -PRESHIFT(0x00026000) /* -0.000579834 */, + PRESHIFT(0x000e1000) /* 0.003433228 */, + -PRESHIFT(0x00285000) /* -0.009841919 */, + PRESHIFT(0x00765000) /* 0.028884888 */, + -PRESHIFT(0x0185d000) /* -0.095169067 */, + PRESHIFT(0x011d1000) /* 0.069595337 */, + -PRESHIFT(0x0a7fe000) /* -0.656219482 */, + PRESHIFT(0x12386000) /* 1.138763428 */, + PRESHIFT(0x07ccb000) /* 0.487472534 */, + PRESHIFT(0x01f9c000) /* 0.123474121 */, + PRESHIFT(0x00fdf000) /* 0.061996460 */, + PRESHIFT(0x00827000) /* 0.031845093 */, + PRESHIFT(0x00126000) /* 0.004486084 */, + PRESHIFT(0x000c4000) /* 0.002990723 */, + PRESHIFT(0x00015000) /* 0.000320435 */, + + -PRESHIFT(0x00001000) /* -0.000015259 */, + -PRESHIFT(0x00026000) /* -0.000579834 */, + PRESHIFT(0x000e1000) /* 0.003433228 */, + -PRESHIFT(0x00285000) /* -0.009841919 */, + PRESHIFT(0x00765000) /* 0.028884888 */, + -PRESHIFT(0x0185d000) /* -0.095169067 */, + PRESHIFT(0x011d1000) /* 0.069595337 */, + -PRESHIFT(0x0a7fe000) /* -0.656219482 */, + PRESHIFT(0x12386000) /* 1.138763428 */, + PRESHIFT(0x07ccb000) /* 0.487472534 */, + PRESHIFT(0x01f9c000) /* 0.123474121 */, + PRESHIFT(0x00fdf000) /* 0.061996460 */, + PRESHIFT(0x00827000) /* 0.031845093 */, + PRESHIFT(0x00126000) /* 0.004486084 */, + PRESHIFT(0x000c4000) /* 0.002990723 */, + PRESHIFT(0x00015000) /* 0.000320435 */ }, + + { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 4 */ + -PRESHIFT(0x00029000) /* -0.000625610 */, + PRESHIFT(0x000e3000) /* 0.003463745 */, + -PRESHIFT(0x002c7000) /* -0.010848999 */, + PRESHIFT(0x0071e000) /* 0.027801514 */, + -PRESHIFT(0x019bd000) /* -0.100540161 */, + PRESHIFT(0x00ec0000) /* 0.057617187 */, + -PRESHIFT(0x0af15000) /* -0.683914185 */, + PRESHIFT(0x12249000) /* 1.133926392 */, + PRESHIFT(0x075a0000) /* 0.459472656 */, + PRESHIFT(0x0212c000) /* 0.129577637 */, + PRESHIFT(0x00e79000) /* 0.056533813 */, + PRESHIFT(0x00825000) /* 0.031814575 */, + PRESHIFT(0x000f4000) /* 0.003723145 */, + PRESHIFT(0x000be000) /* 0.002899170 */, + PRESHIFT(0x00013000) /* 0.000289917 */, + + -PRESHIFT(0x00001000) /* -0.000015259 */, + -PRESHIFT(0x00029000) /* -0.000625610 */, + PRESHIFT(0x000e3000) /* 0.003463745 */, + -PRESHIFT(0x002c7000) /* -0.010848999 */, + PRESHIFT(0x0071e000) /* 0.027801514 */, + -PRESHIFT(0x019bd000) /* -0.100540161 */, + PRESHIFT(0x00ec0000) /* 0.057617187 */, + -PRESHIFT(0x0af15000) /* -0.683914185 */, + PRESHIFT(0x12249000) /* 1.133926392 */, + PRESHIFT(0x075a0000) /* 0.459472656 */, + PRESHIFT(0x0212c000) /* 0.129577637 */, + PRESHIFT(0x00e79000) /* 0.056533813 */, + PRESHIFT(0x00825000) /* 0.031814575 */, + PRESHIFT(0x000f4000) /* 0.003723145 */, + PRESHIFT(0x000be000) /* 0.002899170 */, + PRESHIFT(0x00013000) /* 0.000289917 */ }, + + { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 5 */ + -PRESHIFT(0x0002d000) /* -0.000686646 */, + PRESHIFT(0x000e4000) /* 0.003479004 */, + -PRESHIFT(0x0030b000) /* -0.011886597 */, + PRESHIFT(0x006cb000) /* 0.026535034 */, + -PRESHIFT(0x01b17000) /* -0.105819702 */, + PRESHIFT(0x00b77000) /* 0.044784546 */, + -PRESHIFT(0x0b619000) /* -0.711318970 */, + PRESHIFT(0x120b4000) /* 1.127746582 */, + PRESHIFT(0x06e81000) /* 0.431655884 */, + PRESHIFT(0x02288000) /* 0.134887695 */, + PRESHIFT(0x00d17000) /* 0.051132202 */, + PRESHIFT(0x0081b000) /* 0.031661987 */, + PRESHIFT(0x000c5000) /* 0.003005981 */, + PRESHIFT(0x000b7000) /* 0.002792358 */, + PRESHIFT(0x00011000) /* 0.000259399 */, + + -PRESHIFT(0x00001000) /* -0.000015259 */, + -PRESHIFT(0x0002d000) /* -0.000686646 */, + PRESHIFT(0x000e4000) /* 0.003479004 */, + -PRESHIFT(0x0030b000) /* -0.011886597 */, + PRESHIFT(0x006cb000) /* 0.026535034 */, + -PRESHIFT(0x01b17000) /* -0.105819702 */, + PRESHIFT(0x00b77000) /* 0.044784546 */, + -PRESHIFT(0x0b619000) /* -0.711318970 */, + PRESHIFT(0x120b4000) /* 1.127746582 */, + PRESHIFT(0x06e81000) /* 0.431655884 */, + PRESHIFT(0x02288000) /* 0.134887695 */, + PRESHIFT(0x00d17000) /* 0.051132202 */, + PRESHIFT(0x0081b000) /* 0.031661987 */, + PRESHIFT(0x000c5000) /* 0.003005981 */, + PRESHIFT(0x000b7000) /* 0.002792358 */, + PRESHIFT(0x00011000) /* 0.000259399 */ }, + + { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 6 */ + -PRESHIFT(0x00031000) /* -0.000747681 */, + PRESHIFT(0x000e4000) /* 0.003479004 */, + -PRESHIFT(0x00350000) /* -0.012939453 */, + PRESHIFT(0x0066c000) /* 0.025085449 */, + -PRESHIFT(0x01c67000) /* -0.110946655 */, + PRESHIFT(0x007f5000) /* 0.031082153 */, + -PRESHIFT(0x0bd06000) /* -0.738372803 */, + PRESHIFT(0x11ec7000) /* 1.120223999 */, + PRESHIFT(0x06772000) /* 0.404083252 */, + PRESHIFT(0x023b3000) /* 0.139450073 */, + PRESHIFT(0x00bbc000) /* 0.045837402 */, + PRESHIFT(0x00809000) /* 0.031387329 */, + PRESHIFT(0x00099000) /* 0.002334595 */, + PRESHIFT(0x000b0000) /* 0.002685547 */, + PRESHIFT(0x00010000) /* 0.000244141 */, + + -PRESHIFT(0x00001000) /* -0.000015259 */, + -PRESHIFT(0x00031000) /* -0.000747681 */, + PRESHIFT(0x000e4000) /* 0.003479004 */, + -PRESHIFT(0x00350000) /* -0.012939453 */, + PRESHIFT(0x0066c000) /* 0.025085449 */, + -PRESHIFT(0x01c67000) /* -0.110946655 */, + PRESHIFT(0x007f5000) /* 0.031082153 */, + -PRESHIFT(0x0bd06000) /* -0.738372803 */, + PRESHIFT(0x11ec7000) /* 1.120223999 */, + PRESHIFT(0x06772000) /* 0.404083252 */, + PRESHIFT(0x023b3000) /* 0.139450073 */, + PRESHIFT(0x00bbc000) /* 0.045837402 */, + PRESHIFT(0x00809000) /* 0.031387329 */, + PRESHIFT(0x00099000) /* 0.002334595 */, + PRESHIFT(0x000b0000) /* 0.002685547 */, + PRESHIFT(0x00010000) /* 0.000244141 */ }, + + { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 7 */ + -PRESHIFT(0x00035000) /* -0.000808716 */, + PRESHIFT(0x000e3000) /* 0.003463745 */, + -PRESHIFT(0x00397000) /* -0.014022827 */, + PRESHIFT(0x005ff000) /* 0.023422241 */, + -PRESHIFT(0x01dad000) /* -0.115921021 */, + PRESHIFT(0x0043a000) /* 0.016510010 */, + -PRESHIFT(0x0c3d9000) /* -0.765029907 */, + PRESHIFT(0x11c83000) /* 1.111373901 */, + PRESHIFT(0x06076000) /* 0.376800537 */, + PRESHIFT(0x024ad000) /* 0.143264771 */, + PRESHIFT(0x00a67000) /* 0.040634155 */, + PRESHIFT(0x007f0000) /* 0.031005859 */, + PRESHIFT(0x0006f000) /* 0.001693726 */, + PRESHIFT(0x000a9000) /* 0.002578735 */, + PRESHIFT(0x0000e000) /* 0.000213623 */, + + -PRESHIFT(0x00002000) /* -0.000030518 */, + -PRESHIFT(0x00035000) /* -0.000808716 */, + PRESHIFT(0x000e3000) /* 0.003463745 */, + -PRESHIFT(0x00397000) /* -0.014022827 */, + PRESHIFT(0x005ff000) /* 0.023422241 */, + -PRESHIFT(0x01dad000) /* -0.115921021 */, + PRESHIFT(0x0043a000) /* 0.016510010 */, + -PRESHIFT(0x0c3d9000) /* -0.765029907 */, + PRESHIFT(0x11c83000) /* 1.111373901 */, + PRESHIFT(0x06076000) /* 0.376800537 */, + PRESHIFT(0x024ad000) /* 0.143264771 */, + PRESHIFT(0x00a67000) /* 0.040634155 */, + PRESHIFT(0x007f0000) /* 0.031005859 */, + PRESHIFT(0x0006f000) /* 0.001693726 */, + PRESHIFT(0x000a9000) /* 0.002578735 */, + PRESHIFT(0x0000e000) /* 0.000213623 */ }, + + { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 8 */ + -PRESHIFT(0x0003a000) /* -0.000885010 */, + PRESHIFT(0x000e0000) /* 0.003417969 */, + -PRESHIFT(0x003df000) /* -0.015121460 */, + PRESHIFT(0x00586000) /* 0.021575928 */, + -PRESHIFT(0x01ee6000) /* -0.120697021 */, + PRESHIFT(0x00046000) /* 0.001068115 */, + -PRESHIFT(0x0ca8d000) /* -0.791213989 */, + PRESHIFT(0x119e9000) /* 1.101211548 */, + PRESHIFT(0x05991000) /* 0.349868774 */, + PRESHIFT(0x02578000) /* 0.146362305 */, + PRESHIFT(0x0091a000) /* 0.035552979 */, + PRESHIFT(0x007d1000) /* 0.030532837 */, + PRESHIFT(0x00048000) /* 0.001098633 */, + PRESHIFT(0x000a1000) /* 0.002456665 */, + PRESHIFT(0x0000d000) /* 0.000198364 */, + + -PRESHIFT(0x00002000) /* -0.000030518 */, + -PRESHIFT(0x0003a000) /* -0.000885010 */, + PRESHIFT(0x000e0000) /* 0.003417969 */, + -PRESHIFT(0x003df000) /* -0.015121460 */, + PRESHIFT(0x00586000) /* 0.021575928 */, + -PRESHIFT(0x01ee6000) /* -0.120697021 */, + PRESHIFT(0x00046000) /* 0.001068115 */, + -PRESHIFT(0x0ca8d000) /* -0.791213989 */, + PRESHIFT(0x119e9000) /* 1.101211548 */, + PRESHIFT(0x05991000) /* 0.349868774 */, + PRESHIFT(0x02578000) /* 0.146362305 */, + PRESHIFT(0x0091a000) /* 0.035552979 */, + PRESHIFT(0x007d1000) /* 0.030532837 */, + PRESHIFT(0x00048000) /* 0.001098633 */, + PRESHIFT(0x000a1000) /* 0.002456665 */, + PRESHIFT(0x0000d000) /* 0.000198364 */ }, + + { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 9 */ + -PRESHIFT(0x0003f000) /* -0.000961304 */, + PRESHIFT(0x000dd000) /* 0.003372192 */, + -PRESHIFT(0x00428000) /* -0.016235352 */, + PRESHIFT(0x00500000) /* 0.019531250 */, + -PRESHIFT(0x02011000) /* -0.125259399 */, + -PRESHIFT(0x003e6000) /* -0.015228271 */, + -PRESHIFT(0x0d11e000) /* -0.816864014 */, + PRESHIFT(0x116fc000) /* 1.089782715 */, + PRESHIFT(0x052c5000) /* 0.323318481 */, + PRESHIFT(0x02616000) /* 0.148773193 */, + PRESHIFT(0x007d6000) /* 0.030609131 */, + PRESHIFT(0x007aa000) /* 0.029937744 */, + PRESHIFT(0x00024000) /* 0.000549316 */, + PRESHIFT(0x0009a000) /* 0.002349854 */, + PRESHIFT(0x0000b000) /* 0.000167847 */, + + -PRESHIFT(0x00002000) /* -0.000030518 */, + -PRESHIFT(0x0003f000) /* -0.000961304 */, + PRESHIFT(0x000dd000) /* 0.003372192 */, + -PRESHIFT(0x00428000) /* -0.016235352 */, + PRESHIFT(0x00500000) /* 0.019531250 */, + -PRESHIFT(0x02011000) /* -0.125259399 */, + -PRESHIFT(0x003e6000) /* -0.015228271 */, + -PRESHIFT(0x0d11e000) /* -0.816864014 */, + PRESHIFT(0x116fc000) /* 1.089782715 */, + PRESHIFT(0x052c5000) /* 0.323318481 */, + PRESHIFT(0x02616000) /* 0.148773193 */, + PRESHIFT(0x007d6000) /* 0.030609131 */, + PRESHIFT(0x007aa000) /* 0.029937744 */, + PRESHIFT(0x00024000) /* 0.000549316 */, + PRESHIFT(0x0009a000) /* 0.002349854 */, + PRESHIFT(0x0000b000) /* 0.000167847 */ }, + + { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 10 */ + -PRESHIFT(0x00044000) /* -0.001037598 */, + PRESHIFT(0x000d7000) /* 0.003280640 */, + -PRESHIFT(0x00471000) /* -0.017349243 */, + PRESHIFT(0x0046b000) /* 0.017257690 */, + -PRESHIFT(0x0212b000) /* -0.129562378 */, + -PRESHIFT(0x0084a000) /* -0.032379150 */, + -PRESHIFT(0x0d78a000) /* -0.841949463 */, + PRESHIFT(0x113be000) /* 1.077117920 */, + PRESHIFT(0x04c16000) /* 0.297210693 */, + PRESHIFT(0x02687000) /* 0.150497437 */, + PRESHIFT(0x0069c000) /* 0.025817871 */, + PRESHIFT(0x0077f000) /* 0.029281616 */, + PRESHIFT(0x00002000) /* 0.000030518 */, + PRESHIFT(0x00093000) /* 0.002243042 */, + PRESHIFT(0x0000a000) /* 0.000152588 */, + + -PRESHIFT(0x00002000) /* -0.000030518 */, + -PRESHIFT(0x00044000) /* -0.001037598 */, + PRESHIFT(0x000d7000) /* 0.003280640 */, + -PRESHIFT(0x00471000) /* -0.017349243 */, + PRESHIFT(0x0046b000) /* 0.017257690 */, + -PRESHIFT(0x0212b000) /* -0.129562378 */, + -PRESHIFT(0x0084a000) /* -0.032379150 */, + -PRESHIFT(0x0d78a000) /* -0.841949463 */, + PRESHIFT(0x113be000) /* 1.077117920 */, + PRESHIFT(0x04c16000) /* 0.297210693 */, + PRESHIFT(0x02687000) /* 0.150497437 */, + PRESHIFT(0x0069c000) /* 0.025817871 */, + PRESHIFT(0x0077f000) /* 0.029281616 */, + PRESHIFT(0x00002000) /* 0.000030518 */, + PRESHIFT(0x00093000) /* 0.002243042 */, + PRESHIFT(0x0000a000) /* 0.000152588 */ }, + + { -PRESHIFT(0x00003000) /* -0.000045776 */, /* 11 */ + -PRESHIFT(0x00049000) /* -0.001113892 */, + PRESHIFT(0x000d0000) /* 0.003173828 */, + -PRESHIFT(0x004ba000) /* -0.018463135 */, + PRESHIFT(0x003ca000) /* 0.014801025 */, + -PRESHIFT(0x02233000) /* -0.133590698 */, + -PRESHIFT(0x00ce4000) /* -0.050354004 */, + -PRESHIFT(0x0ddca000) /* -0.866363525 */, + PRESHIFT(0x1102f000) /* 1.063217163 */, + PRESHIFT(0x04587000) /* 0.271591187 */, + PRESHIFT(0x026cf000) /* 0.151596069 */, + PRESHIFT(0x0056c000) /* 0.021179199 */, + PRESHIFT(0x0074e000) /* 0.028533936 */, + -PRESHIFT(0x0001d000) /* -0.000442505 */, + PRESHIFT(0x0008b000) /* 0.002120972 */, + PRESHIFT(0x00009000) /* 0.000137329 */, + + -PRESHIFT(0x00003000) /* -0.000045776 */, + -PRESHIFT(0x00049000) /* -0.001113892 */, + PRESHIFT(0x000d0000) /* 0.003173828 */, + -PRESHIFT(0x004ba000) /* -0.018463135 */, + PRESHIFT(0x003ca000) /* 0.014801025 */, + -PRESHIFT(0x02233000) /* -0.133590698 */, + -PRESHIFT(0x00ce4000) /* -0.050354004 */, + -PRESHIFT(0x0ddca000) /* -0.866363525 */, + PRESHIFT(0x1102f000) /* 1.063217163 */, + PRESHIFT(0x04587000) /* 0.271591187 */, + PRESHIFT(0x026cf000) /* 0.151596069 */, + PRESHIFT(0x0056c000) /* 0.021179199 */, + PRESHIFT(0x0074e000) /* 0.028533936 */, + -PRESHIFT(0x0001d000) /* -0.000442505 */, + PRESHIFT(0x0008b000) /* 0.002120972 */, + PRESHIFT(0x00009000) /* 0.000137329 */ }, + + { -PRESHIFT(0x00003000) /* -0.000045776 */, /* 12 */ + -PRESHIFT(0x0004f000) /* -0.001205444 */, + PRESHIFT(0x000c8000) /* 0.003051758 */, + -PRESHIFT(0x00503000) /* -0.019577026 */, + PRESHIFT(0x0031a000) /* 0.012115479 */, + -PRESHIFT(0x02326000) /* -0.137298584 */, + -PRESHIFT(0x011b5000) /* -0.069168091 */, + -PRESHIFT(0x0e3dd000) /* -0.890090942 */, + PRESHIFT(0x10c54000) /* 1.048156738 */, + PRESHIFT(0x03f1b000) /* 0.246505737 */, + PRESHIFT(0x026ee000) /* 0.152069092 */, + PRESHIFT(0x00447000) /* 0.016708374 */, + PRESHIFT(0x00719000) /* 0.027725220 */, + -PRESHIFT(0x00039000) /* -0.000869751 */, + PRESHIFT(0x00084000) /* 0.002014160 */, + PRESHIFT(0x00008000) /* 0.000122070 */, + + -PRESHIFT(0x00003000) /* -0.000045776 */, + -PRESHIFT(0x0004f000) /* -0.001205444 */, + PRESHIFT(0x000c8000) /* 0.003051758 */, + -PRESHIFT(0x00503000) /* -0.019577026 */, + PRESHIFT(0x0031a000) /* 0.012115479 */, + -PRESHIFT(0x02326000) /* -0.137298584 */, + -PRESHIFT(0x011b5000) /* -0.069168091 */, + -PRESHIFT(0x0e3dd000) /* -0.890090942 */, + PRESHIFT(0x10c54000) /* 1.048156738 */, + PRESHIFT(0x03f1b000) /* 0.246505737 */, + PRESHIFT(0x026ee000) /* 0.152069092 */, + PRESHIFT(0x00447000) /* 0.016708374 */, + PRESHIFT(0x00719000) /* 0.027725220 */, + -PRESHIFT(0x00039000) /* -0.000869751 */, + PRESHIFT(0x00084000) /* 0.002014160 */, + PRESHIFT(0x00008000) /* 0.000122070 */ }, + + { -PRESHIFT(0x00004000) /* -0.000061035 */, /* 13 */ + -PRESHIFT(0x00055000) /* -0.001296997 */, + PRESHIFT(0x000bd000) /* 0.002883911 */, + -PRESHIFT(0x0054c000) /* -0.020690918 */, + PRESHIFT(0x0025d000) /* 0.009231567 */, + -PRESHIFT(0x02403000) /* -0.140670776 */, + -PRESHIFT(0x016ba000) /* -0.088775635 */, + -PRESHIFT(0x0e9be000) /* -0.913055420 */, + PRESHIFT(0x1082d000) /* 1.031936646 */, + PRESHIFT(0x038d4000) /* 0.221984863 */, + PRESHIFT(0x026e7000) /* 0.151962280 */, + PRESHIFT(0x0032e000) /* 0.012420654 */, + PRESHIFT(0x006df000) /* 0.026840210 */, + -PRESHIFT(0x00053000) /* -0.001266479 */, + PRESHIFT(0x0007d000) /* 0.001907349 */, + PRESHIFT(0x00007000) /* 0.000106812 */, + + -PRESHIFT(0x00004000) /* -0.000061035 */, + -PRESHIFT(0x00055000) /* -0.001296997 */, + PRESHIFT(0x000bd000) /* 0.002883911 */, + -PRESHIFT(0x0054c000) /* -0.020690918 */, + PRESHIFT(0x0025d000) /* 0.009231567 */, + -PRESHIFT(0x02403000) /* -0.140670776 */, + -PRESHIFT(0x016ba000) /* -0.088775635 */, + -PRESHIFT(0x0e9be000) /* -0.913055420 */, + PRESHIFT(0x1082d000) /* 1.031936646 */, + PRESHIFT(0x038d4000) /* 0.221984863 */, + PRESHIFT(0x026e7000) /* 0.151962280 */, + PRESHIFT(0x0032e000) /* 0.012420654 */, + PRESHIFT(0x006df000) /* 0.026840210 */, + -PRESHIFT(0x00053000) /* -0.001266479 */, + PRESHIFT(0x0007d000) /* 0.001907349 */, + PRESHIFT(0x00007000) /* 0.000106812 */ }, + + { -PRESHIFT(0x00004000) /* -0.000061035 */, /* 14 */ + -PRESHIFT(0x0005b000) /* -0.001388550 */, + PRESHIFT(0x000b1000) /* 0.002700806 */, + -PRESHIFT(0x00594000) /* -0.021789551 */, + PRESHIFT(0x00192000) /* 0.006134033 */, + -PRESHIFT(0x024c8000) /* -0.143676758 */, + -PRESHIFT(0x01bf2000) /* -0.109161377 */, + -PRESHIFT(0x0ef69000) /* -0.935195923 */, + PRESHIFT(0x103be000) /* 1.014617920 */, + PRESHIFT(0x032b4000) /* 0.198059082 */, + PRESHIFT(0x026bc000) /* 0.151306152 */, + PRESHIFT(0x00221000) /* 0.008316040 */, + PRESHIFT(0x006a2000) /* 0.025909424 */, + -PRESHIFT(0x0006a000) /* -0.001617432 */, + PRESHIFT(0x00075000) /* 0.001785278 */, + PRESHIFT(0x00007000) /* 0.000106812 */, + + -PRESHIFT(0x00004000) /* -0.000061035 */, + -PRESHIFT(0x0005b000) /* -0.001388550 */, + PRESHIFT(0x000b1000) /* 0.002700806 */, + -PRESHIFT(0x00594000) /* -0.021789551 */, + PRESHIFT(0x00192000) /* 0.006134033 */, + -PRESHIFT(0x024c8000) /* -0.143676758 */, + -PRESHIFT(0x01bf2000) /* -0.109161377 */, + -PRESHIFT(0x0ef69000) /* -0.935195923 */, + PRESHIFT(0x103be000) /* 1.014617920 */, + PRESHIFT(0x032b4000) /* 0.198059082 */, + PRESHIFT(0x026bc000) /* 0.151306152 */, + PRESHIFT(0x00221000) /* 0.008316040 */, + PRESHIFT(0x006a2000) /* 0.025909424 */, + -PRESHIFT(0x0006a000) /* -0.001617432 */, + PRESHIFT(0x00075000) /* 0.001785278 */, + PRESHIFT(0x00007000) /* 0.000106812 */ }, + + { -PRESHIFT(0x00005000) /* -0.000076294 */, /* 15 */ + -PRESHIFT(0x00061000) /* -0.001480103 */, + PRESHIFT(0x000a3000) /* 0.002487183 */, + -PRESHIFT(0x005da000) /* -0.022857666 */, + PRESHIFT(0x000b9000) /* 0.002822876 */, + -PRESHIFT(0x02571000) /* -0.146255493 */, + -PRESHIFT(0x0215c000) /* -0.130310059 */, + -PRESHIFT(0x0f4dc000) /* -0.956481934 */, + PRESHIFT(0x0ff0a000) /* 0.996246338 */, + PRESHIFT(0x02cbf000) /* 0.174789429 */, + PRESHIFT(0x0266e000) /* 0.150115967 */, + PRESHIFT(0x00120000) /* 0.004394531 */, + PRESHIFT(0x00662000) /* 0.024932861 */, + -PRESHIFT(0x0007f000) /* -0.001937866 */, + PRESHIFT(0x0006f000) /* 0.001693726 */, + PRESHIFT(0x00006000) /* 0.000091553 */, + + -PRESHIFT(0x00005000) /* -0.000076294 */, + -PRESHIFT(0x00061000) /* -0.001480103 */, + PRESHIFT(0x000a3000) /* 0.002487183 */, + -PRESHIFT(0x005da000) /* -0.022857666 */, + PRESHIFT(0x000b9000) /* 0.002822876 */, + -PRESHIFT(0x02571000) /* -0.146255493 */, + -PRESHIFT(0x0215c000) /* -0.130310059 */, + -PRESHIFT(0x0f4dc000) /* -0.956481934 */, + PRESHIFT(0x0ff0a000) /* 0.996246338 */, + PRESHIFT(0x02cbf000) /* 0.174789429 */, + PRESHIFT(0x0266e000) /* 0.150115967 */, + PRESHIFT(0x00120000) /* 0.004394531 */, + PRESHIFT(0x00662000) /* 0.024932861 */, + -PRESHIFT(0x0007f000) /* -0.001937866 */, + PRESHIFT(0x0006f000) /* 0.001693726 */, + PRESHIFT(0x00006000) /* 0.000091553 */ }, + + { -PRESHIFT(0x00005000) /* -0.000076294 */, /* 16 */ + -PRESHIFT(0x00068000) /* -0.001586914 */, + PRESHIFT(0x00092000) /* 0.002227783 */, + -PRESHIFT(0x0061f000) /* -0.023910522 */, + -PRESHIFT(0x0002d000) /* -0.000686646 */, + -PRESHIFT(0x025ff000) /* -0.148422241 */, + -PRESHIFT(0x026f7000) /* -0.152206421 */, + -PRESHIFT(0x0fa13000) /* -0.976852417 */, + PRESHIFT(0x0fa13000) /* 0.976852417 */, + PRESHIFT(0x026f7000) /* 0.152206421 */, + PRESHIFT(0x025ff000) /* 0.148422241 */, + PRESHIFT(0x0002d000) /* 0.000686646 */, + PRESHIFT(0x0061f000) /* 0.023910522 */, + -PRESHIFT(0x00092000) /* -0.002227783 */, + PRESHIFT(0x00068000) /* 0.001586914 */, + PRESHIFT(0x00005000) /* 0.000076294 */, + + -PRESHIFT(0x00005000) /* -0.000076294 */, + -PRESHIFT(0x00068000) /* -0.001586914 */, + PRESHIFT(0x00092000) /* 0.002227783 */, + -PRESHIFT(0x0061f000) /* -0.023910522 */, + -PRESHIFT(0x0002d000) /* -0.000686646 */, + -PRESHIFT(0x025ff000) /* -0.148422241 */, + -PRESHIFT(0x026f7000) /* -0.152206421 */, + -PRESHIFT(0x0fa13000) /* -0.976852417 */, + PRESHIFT(0x0fa13000) /* 0.976852417 */, + PRESHIFT(0x026f7000) /* 0.152206421 */, + PRESHIFT(0x025ff000) /* 0.148422241 */, + PRESHIFT(0x0002d000) /* 0.000686646 */, + PRESHIFT(0x0061f000) /* 0.023910522 */, + -PRESHIFT(0x00092000) /* -0.002227783 */, + PRESHIFT(0x00068000) /* 0.001586914 */, + PRESHIFT(0x00005000) /* 0.000076294 */ } diff --git a/core/multimedia/opieplayer/libmad/Makefile.in b/core/multimedia/opieplayer/libmad/Makefile.in new file mode 100644 index 0000000..9e17769 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/Makefile.in @@ -0,0 +1,226 @@ +############################################################################# + +####### Compiler, tools and options + +CXX = $(SYSCONF_CXX) $(QT_CXX_MT) +CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) -DQCONFIG=\"qpe\" +CC = $(SYSCONF_CC) $(QT_C_MT) +CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) -DQCONFIG=\"qpe\" +INCPATH = -I$(QPEDIR)/include -I.. +LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) +LIBS = $(SUBLIBS) -lqpe -lm $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP) +MOC = $(SYSCONF_MOC) +UIC = $(SYSCONF_UIC) + +####### Target + +DESTDIR = ../../plugins/codecs/ +VER_MAJ = 1 +VER_MIN = 0 +VER_PATCH = 0 +TARGET = madplugin +TARGET1 = lib$(TARGET).so.$(VER_MAJ) + +####### Files + +HEADERS = libmad_version.h \ + fixed.h \ + bit.h \ + timer.h \ + stream.h \ + frame.h \ + synth.h \ + decoder.h \ + layer12.h \ + layer3.h \ + huffman.h \ + libmad_global.h \ + mad.h \ + libmadplugin.h \ + libmadpluginimpl.h +SOURCES = version.c \ + fixed.c \ + bit.c \ + timer.c \ + stream.c \ + frame.c \ + synth.c \ + decoder.c \ + layer12.c \ + layer3.c \ + huffman.c \ + libmadplugin.cpp \ + libmadpluginimpl.cpp +OBJECTS = version.o \ + fixed.o \ + bit.o \ + timer.o \ + stream.o \ + frame.o \ + synth.o \ + decoder.o \ + layer12.o \ + layer3.o \ + huffman.o \ + libmadplugin.o \ + libmadpluginimpl.o +INTERFACES = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = + + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + + +all: $(DESTDIR)$(SYSCONF_LINK_TARGET) + +$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) + $(SYSCONF_LINK_LIB) + +moc: $(SRCMOC) + +tmake: + tmake libmad.pro + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) + -rm -f *~ core + -rm -f allmoc.cpp + +####### Extension Modules + +listpromodules: + @echo + +listallmodules: + @echo + +listaddonpromodules: + @echo + +listaddonentmodules: + @echo + + +REQUIRES= + +####### Sub-libraries + + +###### Combined headers + + + +####### Compile + +version.o: version.c \ + libmad_global.h \ + libmad_version.h + +fixed.o: fixed.c \ + libmad_global.h \ + fixed.h + +bit.o: bit.c \ + libmad_global.h \ + bit.h + +timer.o: timer.c \ + libmad_global.h \ + timer.h + +stream.o: stream.c \ + libmad_global.h \ + bit.h \ + stream.h + +frame.o: frame.c \ + libmad_global.h \ + bit.h \ + stream.h \ + frame.h \ + fixed.h \ + timer.h \ + layer12.h \ + layer3.h + +synth.o: synth.c \ + libmad_global.h \ + fixed.h \ + frame.h \ + timer.h \ + stream.h \ + bit.h \ + synth.h \ + D.dat + +decoder.o: decoder.c \ + libmad_global.h \ + stream.h \ + bit.h \ + frame.h \ + fixed.h \ + timer.h \ + synth.h \ + decoder.h + +layer12.o: layer12.c \ + libmad_global.h \ + fixed.h \ + bit.h \ + stream.h \ + frame.h \ + timer.h \ + layer12.h \ + sf_table.dat \ + qc_table.dat + +layer3.o: layer3.c \ + libmad_global.h \ + fixed.h \ + bit.h \ + stream.h \ + frame.h \ + timer.h \ + huffman.h \ + layer3.h \ + rq_table.dat \ + imdct_s.dat + +huffman.o: huffman.c \ + libmad_global.h \ + huffman.h + +libmadplugin.o: libmadplugin.cpp \ + libmadplugin.h \ + ../mediaplayerplugininterface.h \ + mad.h + +libmadpluginimpl.o: libmadpluginimpl.cpp \ + libmadplugin.h \ + ../mediaplayerplugininterface.h \ + libmadpluginimpl.h \ + ../mediaplayerplugininterface.h + + diff --git a/core/multimedia/opieplayer/libmad/bit.c b/core/multimedia/opieplayer/libmad/bit.c new file mode 100644 index 0000000..2466c5f --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/bit.c @@ -0,0 +1,220 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# ifdef HAVE_LIMITS_H +# include +# else +# define CHAR_BIT 8 +# endif + +# include "bit.h" + +/* + * This is the lookup table for computing the CRC-check word. + * As described in section 2.4.3.1 and depicted in Figure A.9 + * of ISO/IEC 11172-3, the generator polynomial is: + * + * G(X) = X^16 + X^15 + X^2 + 1 + */ +static +unsigned short const crc_table[256] = { + 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, + 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, + 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, + 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, + 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, + 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, + 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, + 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, + + 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, + 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, + 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, + 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, + 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, + 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, + 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, + 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, + + 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, + 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, + 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, + 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, + 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, + 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, + 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, + + 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, + 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, + 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, + 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, + 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, + 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, + 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 +}; + +# define CRC_POLY 0x8005 + +/* + * NAME: bit->init() + * DESCRIPTION: initialize bit pointer struct + */ +void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte) +{ + bitptr->byte = byte; + bitptr->cache = 0; + bitptr->left = CHAR_BIT; +} + +/* + * NAME: bit->length() + * DESCRIPTION: return number of bits between start and end points + */ +unsigned int mad_bit_length(struct mad_bitptr const *begin, + struct mad_bitptr const *end) +{ + return begin->left + + CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left); +} + +/* + * NAME: bit->nextbyte() + * DESCRIPTION: return pointer to next unprocessed byte + */ +unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr) +{ + return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1; +} + +/* + * NAME: bit->skip() + * DESCRIPTION: advance bit pointer + */ +void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len) +{ + bitptr->byte += len / CHAR_BIT; + bitptr->left -= len % CHAR_BIT; + + if (bitptr->left > CHAR_BIT) { + bitptr->byte++; + bitptr->left += CHAR_BIT; + } + + if (bitptr->left < CHAR_BIT) + bitptr->cache = *bitptr->byte; +} + +/* + * NAME: bit->read() + * DESCRIPTION: read an arbitrary number of bits and return their UIMSBF value + */ +unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len) +{ + register unsigned long value; + + if (bitptr->left == CHAR_BIT) + bitptr->cache = *bitptr->byte; + + if (len < bitptr->left) { + value = (bitptr->cache & ((1 << bitptr->left) - 1)) >> + (bitptr->left - len); + bitptr->left -= len; + + return value; + } + + /* remaining bits in current byte */ + + value = bitptr->cache & ((1 << bitptr->left) - 1); + len -= bitptr->left; + + bitptr->byte++; + bitptr->left = CHAR_BIT; + + /* more bytes */ + + while (len >= CHAR_BIT) { + value = (value << CHAR_BIT) | *bitptr->byte++; + len -= CHAR_BIT; + } + + if (len > 0) { + bitptr->cache = *bitptr->byte; + + value = (value << len) | (bitptr->cache >> (CHAR_BIT - len)); + bitptr->left -= len; + } + + return value; +} + +# if 0 +/* + * NAME: bit->write() + * DESCRIPTION: write an arbitrary number of bits + */ +void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len, + unsigned long value) +{ + unsigned char *ptr; + + ptr = (unsigned char *) bitptr->byte; + + /* ... */ +} +# endif + +/* + * NAME: bit->crc() + * DESCRIPTION: compute CRC-check word + */ +unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len, + unsigned short init) +{ + register unsigned int crc, data; + +# if CHAR_BIT == 8 + for (crc = init; len >= 8; len -= 8) { + crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + } +# else + crc = init; +# endif + + while (len--) { + data = mad_bit_read(&bitptr, 1) ^ (crc >> 15); + + crc <<= 1; + if (data & 1) + crc ^= CRC_POLY; + } + + return crc & 0xffff; +} diff --git a/core/multimedia/opieplayer/libmad/bit.h b/core/multimedia/opieplayer/libmad/bit.h new file mode 100644 index 0000000..f315bc9 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/bit.h @@ -0,0 +1,47 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_BIT_H +# define LIBMAD_BIT_H + +struct mad_bitptr { + unsigned char const *byte; + unsigned short cache; + unsigned short left; +}; + +void mad_bit_init(struct mad_bitptr *, unsigned char const *); + +# define mad_bit_finish(bitptr) /* nothing */ + +unsigned int mad_bit_length(struct mad_bitptr const *, + struct mad_bitptr const *); + +# define mad_bit_bitsleft(bitptr) ((bitptr)->left) +unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); + +void mad_bit_skip(struct mad_bitptr *, unsigned int); +unsigned long mad_bit_read(struct mad_bitptr *, unsigned int); +void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long); + +unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); + +# endif diff --git a/core/multimedia/opieplayer/libmad/decoder.c b/core/multimedia/opieplayer/libmad/decoder.c new file mode 100644 index 0000000..dcf7cf3 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/decoder.c @@ -0,0 +1,554 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# else +# ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +# endif +# ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +# endif +# endif + +# include "libmad_global.h" + +# include + +# ifdef HAVE_SYS_WAIT_H +# include +# endif + +# ifdef HAVE_UNISTD_H +# include +# endif + +# include +# include +# include + +# include "stream.h" +# include "frame.h" +# include "synth.h" +# include "decoder.h" + +void mad_decoder_init(struct mad_decoder *decoder, void *data, + enum mad_flow (*input_func)(void *, struct mad_stream *), + enum mad_flow (*header_func)(void *, + struct mad_header const *), + enum mad_flow (*filter_func)(void *, struct mad_frame *), + enum mad_flow (*output_func)(void *, + struct mad_header const *, + struct mad_pcm *), + enum mad_flow (*error_func)(void *, struct mad_stream *, + struct mad_frame *), + enum mad_flow (*message_func)(void *, + void *, unsigned int *)) +{ + decoder->mode = -1; + + decoder->options = 0; + + decoder->async.pid = 0; + decoder->async.in = -1; + decoder->async.out = -1; + + decoder->sync = 0; + + decoder->cb_data = data; + + decoder->input_func = input_func; + decoder->header_func = header_func; + decoder->filter_func = filter_func; + decoder->output_func = output_func; + decoder->error_func = error_func; + decoder->message_func = message_func; +} + +int mad_decoder_finish(struct mad_decoder *decoder) +{ + if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) { + pid_t pid; + int status; + + close(decoder->async.in); + + do { + pid = waitpid(decoder->async.pid, &status, 0); + } + while (pid == -1 && errno == EINTR); + + decoder->mode = -1; + + close(decoder->async.out); + + decoder->async.pid = 0; + decoder->async.in = -1; + decoder->async.out = -1; + + if (pid == -1) + return -1; + + return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0; + } + + return 0; +} + +static +enum mad_flow send_io(int fd, void const *data, size_t len) +{ + char const *ptr = data; + ssize_t count; + + while (len) { + do { + count = write(fd, ptr, len); + } + while (count == -1 && errno == EINTR); + + if (count == -1) + return MAD_FLOW_BREAK; + + len -= count; + ptr += count; + } + + return MAD_FLOW_CONTINUE; +} + +static +enum mad_flow receive_io(int fd, void *buffer, size_t len) +{ + char *ptr = buffer; + ssize_t count; + + while (len) { + do { + count = read(fd, ptr, len); + } + while (count == -1 && errno == EINTR); + + if (count == -1) + return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK; + else if (count == 0) + return MAD_FLOW_STOP; + + len -= count; + ptr += count; + } + + return MAD_FLOW_CONTINUE; +} + +static +enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len) +{ + int flags, blocking; + enum mad_flow result; + + flags = fcntl(fd, F_GETFL); + if (flags == -1) + return MAD_FLOW_BREAK; + + blocking = flags & ~O_NONBLOCK; + + if (blocking != flags && + fcntl(fd, F_SETFL, blocking) == -1) + return MAD_FLOW_BREAK; + + result = receive_io(fd, buffer, len); + + if (flags != blocking && + fcntl(fd, F_SETFL, flags) == -1) + return MAD_FLOW_BREAK; + + return result; +} + +static +enum mad_flow send(int fd, void const *message, unsigned int size) +{ + enum mad_flow result; + + /* send size */ + + result = send_io(fd, &size, sizeof(size)); + + /* send message */ + + if (result == MAD_FLOW_CONTINUE) + result = send_io(fd, message, size); + + return result; +} + +static +enum mad_flow receive(int fd, void **message, unsigned int *size) +{ + enum mad_flow result; + unsigned int actual; + + if (*message == 0) + *size = 0; + + /* receive size */ + + result = receive_io(fd, &actual, sizeof(actual)); + + /* receive message */ + + if (result == MAD_FLOW_CONTINUE) { + if (actual > *size) + actual -= *size; + else { + *size = actual; + actual = 0; + } + + if (*size > 0) { + if (*message == 0) { + *message = malloc(*size); + if (*message == 0) + return MAD_FLOW_BREAK; + } + + result = receive_io_blocking(fd, *message, *size); + } + + /* throw away remainder of message */ + + while (actual && result == MAD_FLOW_CONTINUE) { + char sink[256]; + unsigned int len; + + len = actual > sizeof(sink) ? sizeof(sink) : actual; + + result = receive_io_blocking(fd, sink, len); + + actual -= len; + } + } + + return result; +} + +static +enum mad_flow check_message(struct mad_decoder *decoder) +{ + enum mad_flow result; + void *message = 0; + unsigned int size; + + result = receive(decoder->async.in, &message, &size); + + if (result == MAD_FLOW_CONTINUE) { + if (decoder->message_func == 0) + size = 0; + else { + result = decoder->message_func(decoder->cb_data, message, &size); + + if (result == MAD_FLOW_IGNORE || + result == MAD_FLOW_BREAK) + size = 0; + } + + if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE) + result = MAD_FLOW_BREAK; + } + + if (message) + free(message); + + return result; +} + +static +enum mad_flow error_default(void *data, struct mad_stream *stream, + struct mad_frame *frame) +{ + int *bad_last_frame = data; + + switch (stream->error) { + case MAD_ERROR_BADCRC: + if (*bad_last_frame) + mad_frame_mute(frame); + else + *bad_last_frame = 1; + + return MAD_FLOW_IGNORE; + + default: + return MAD_FLOW_CONTINUE; + } +} + +static +int run_sync(struct mad_decoder *decoder) +{ + enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); + void *error_data; + int bad_last_frame = 0; + struct mad_stream *stream; + struct mad_frame *frame; + struct mad_synth *synth; + int result = 0; + + if (decoder->input_func == 0) + return 0; + + if (decoder->error_func) { + error_func = decoder->error_func; + error_data = decoder->cb_data; + } + else { + error_func = error_default; + error_data = &bad_last_frame; + } + + stream = &decoder->sync->stream; + frame = &decoder->sync->frame; + synth = &decoder->sync->synth; + + mad_stream_init(stream); + mad_frame_init(frame); + mad_synth_init(synth); + + mad_stream_options(stream, decoder->options); + + do { + switch (decoder->input_func(decoder->cb_data, stream)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + continue; + case MAD_FLOW_CONTINUE: + break; + } + + while (1) { + if (decoder->mode == MAD_DECODER_MODE_ASYNC) { + switch (check_message(decoder)) { + case MAD_FLOW_IGNORE: + case MAD_FLOW_CONTINUE: + break; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_STOP: + goto done; + } + } + + if (decoder->header_func) { + if (mad_header_decode(&frame->header, stream) == -1) { + if (!MAD_RECOVERABLE(stream->error)) + break; + + switch (error_func(error_data, stream, frame)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + case MAD_FLOW_CONTINUE: + default: + continue; + } + } + + switch (decoder->header_func(decoder->cb_data, &frame->header)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + continue; + case MAD_FLOW_CONTINUE: + break; + } + } + + if (mad_frame_decode(frame, stream) == -1) { + if (!MAD_RECOVERABLE(stream->error)) + break; + + switch (error_func(error_data, stream, frame)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + break; + case MAD_FLOW_CONTINUE: + default: + continue; + } + } + else + bad_last_frame = 0; + + if (decoder->filter_func) { + switch (decoder->filter_func(decoder->cb_data, frame)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + continue; + case MAD_FLOW_CONTINUE: + break; + } + } + + mad_synth_frame(synth, frame); + + if (decoder->output_func) { + switch (decoder->output_func(decoder->cb_data, + &frame->header, &synth->pcm)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + case MAD_FLOW_CONTINUE: + break; + } + } + } + } + while (stream->error == MAD_ERROR_BUFLEN); + + fail: + result = -1; + + done: + mad_synth_finish(synth); + mad_frame_finish(frame); + mad_stream_finish(stream); + + return result; +} + +static +int run_async(struct mad_decoder *decoder) +{ + pid_t pid; + int ptoc[2], ctop[2], flags; + + if (pipe(ptoc) == -1) + return -1; + + if (pipe(ctop) == -1) { + close(ptoc[0]); + close(ptoc[1]); + return -1; + } + + flags = fcntl(ptoc[0], F_GETFL); + if (flags == -1 || + fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) { + close(ctop[0]); + close(ctop[1]); + close(ptoc[0]); + close(ptoc[1]); + return -1; + } + + pid = fork(); + if (pid == -1) { + close(ctop[0]); + close(ctop[1]); + close(ptoc[0]); + close(ptoc[1]); + return -1; + } + + decoder->async.pid = pid; + + if (pid) { + /* parent */ + + close(ptoc[0]); + close(ctop[1]); + + decoder->async.in = ctop[0]; + decoder->async.out = ptoc[1]; + + return 0; + } + + /* child */ + + close(ptoc[1]); + close(ctop[0]); + + decoder->async.in = ptoc[0]; + decoder->async.out = ctop[1]; + + _exit(run_sync(decoder)); + + /* not reached */ + return -1; +} + +int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode) +{ + int result; + int (*run)(struct mad_decoder *) = 0; + + switch (decoder->mode = mode) { + case MAD_DECODER_MODE_SYNC: + run = run_sync; + break; + + case MAD_DECODER_MODE_ASYNC: + run = run_async; + break; + } + + if (run == 0) + return -1; + + decoder->sync = malloc(sizeof(*decoder->sync)); + if (decoder->sync == 0) + return -1; + + result = run(decoder); + + free(decoder->sync); + decoder->sync = 0; + + return result; +} + +int mad_decoder_message(struct mad_decoder *decoder, + void *message, unsigned int *len) +{ + if (decoder->mode != MAD_DECODER_MODE_ASYNC || + send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE || + receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE) + return -1; + + return 0; +} diff --git a/core/multimedia/opieplayer/libmad/decoder.h b/core/multimedia/opieplayer/libmad/decoder.h new file mode 100644 index 0000000..dbacc1a --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/decoder.h @@ -0,0 +1,87 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_DECODER_H +# define LIBMAD_DECODER_H + +# include "stream.h" +# include "frame.h" +# include "synth.h" + +enum mad_decoder_mode { + MAD_DECODER_MODE_SYNC = 0, + MAD_DECODER_MODE_ASYNC +}; + +enum mad_flow { + MAD_FLOW_CONTINUE = 0x0000, + MAD_FLOW_STOP = 0x0010, + MAD_FLOW_BREAK = 0x0011, + MAD_FLOW_IGNORE = 0x0020 +}; + +struct mad_decoder { + enum mad_decoder_mode mode; + + int options; + + struct { + long pid; + int in; + int out; + } async; + + struct { + struct mad_stream stream; + struct mad_frame frame; + struct mad_synth synth; + } *sync; + + void *cb_data; + + enum mad_flow (*input_func)(void *, struct mad_stream *); + enum mad_flow (*header_func)(void *, struct mad_header const *); + enum mad_flow (*filter_func)(void *, struct mad_frame *); + enum mad_flow (*output_func)(void *, + struct mad_header const *, struct mad_pcm *); + enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); + enum mad_flow (*message_func)(void *, void *, unsigned int *); +}; + +void mad_decoder_init(struct mad_decoder *, void *, + enum mad_flow (*)(void *, struct mad_stream *), + enum mad_flow (*)(void *, struct mad_header const *), + enum mad_flow (*)(void *, struct mad_frame *), + enum mad_flow (*)(void *, + struct mad_header const *, + struct mad_pcm *), + enum mad_flow (*)(void *, + struct mad_stream *, + struct mad_frame *), + enum mad_flow (*)(void *, void *, unsigned int *)); +int mad_decoder_finish(struct mad_decoder *); + +# define mad_decoder_options(decoder, opts) ((decoder)->options = (opts)) + +int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); +int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); + +# endif diff --git a/core/multimedia/opieplayer/libmad/fix_headers_problem b/core/multimedia/opieplayer/libmad/fix_headers_problem new file mode 100755 index 0000000..6a5595c --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/fix_headers_problem @@ -0,0 +1,25 @@ +#!/bin/sh + +# +# This is needed to ensure the single build will work +# The names of the header files clash with names of other headers in Qt/Palmtop +# + + +for file in *.c +do + + echo "fixing $file" + sed "s/global.h/libmad_global.h/" $file > $file.tmp + sed "s/version.h/libmad_version.h/" $file.tmp > $file + sed "s/config.h/libmad_config.h/" $file > $file.tmp + mv $file.tmp $file + +done + + +mv global.h libmad_global.h +mv version.h libmad_version.h +mv config.h libmad_config.h + + diff --git a/core/multimedia/opieplayer/libmad/fixed.c b/core/multimedia/opieplayer/libmad/fixed.c new file mode 100644 index 0000000..be5c94e --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/fixed.c @@ -0,0 +1,37 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# include "fixed.h" + +/* + * NAME: fixed->abs() + * DESCRIPTION: return absolute value of a fixed-point number + */ +mad_fixed_t mad_f_abs(mad_fixed_t x) +{ + return x < 0 ? -x : x; +} diff --git a/core/multimedia/opieplayer/libmad/fixed.h b/core/multimedia/opieplayer/libmad/fixed.h new file mode 100644 index 0000000..00ade62 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/fixed.h @@ -0,0 +1,413 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_FIXED_H +# define LIBMAD_FIXED_H + +# if SIZEOF_INT >= 4 +typedef signed int mad_fixed_t; + +typedef signed int mad_fixed64hi_t; +typedef unsigned int mad_fixed64lo_t; +# else +typedef signed long mad_fixed_t; + +typedef signed long mad_fixed64hi_t; +typedef unsigned long mad_fixed64lo_t; +# endif + +/* + * Fixed-point format: 0xABBBBBBB + * A == whole part (sign + 3 bits) + * B == fractional part (28 bits) + * + * Values are signed two's complement, so the effective range is: + * 0x80000000 to 0x7fffffff + * -8.0 to +7.9999999962747097015380859375 + * + * The smallest representable value is: + * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) + * + * 28 bits of fractional accuracy represent about + * 8.6 digits of decimal accuracy. + * + * Fixed-point numbers can be added or subtracted as normal + * integers, but multiplication requires shifting the 64-bit result + * from 56 fractional bits back to 28 (and rounding.) + * + * Changing the definition of MAD_F_FRACBITS is only partially + * supported, and must be done with care. + */ + +# define MAD_F_FRACBITS 28 + +# if MAD_F_FRACBITS == 28 +# define MAD_F(x) ((mad_fixed_t) (x##L)) +# else +# if MAD_F_FRACBITS < 28 +# warning "MAD_F_FRACBITS < 28" +# define MAD_F(x) ((mad_fixed_t) \ + (((x##L) + \ + (1L << (28 - MAD_F_FRACBITS - 1))) >> \ + (28 - MAD_F_FRACBITS))) +# elif MAD_F_FRACBITS > 28 +# error "MAD_F_FRACBITS > 28 not currently supported" +# define MAD_F(x) ((mad_fixed_t) \ + ((x##L) << (MAD_F_FRACBITS - 28))) +# endif +# endif + +# define MAD_F_MIN ((mad_fixed_t) -0x80000000L) +# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL) + +# define MAD_F_ONE MAD_F(0x10000000) + +# define mad_f_tofixed(x) ((mad_fixed_t) \ + ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5)) +# define mad_f_todouble(x) ((double) \ + ((x) / (double) (1L << MAD_F_FRACBITS))) + +# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) +# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) + /* (x should be positive) */ + +# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) + +# define mad_f_add(x, y) ((x) + (y)) +# define mad_f_sub(x, y) ((x) - (y)) + +# if defined(FPM_64BIT) + +/* + * This version should be the most accurate if 64-bit (long long) types are + * supported by the compiler, although it may not be the most efficient. + */ +# if defined(OPT_ACCURACY) +# define mad_f_mul(x, y) \ + ((mad_fixed_t) \ + ((((signed long long) (x) * (y)) + \ + (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS)) +# else +# define mad_f_mul(x, y) \ + ((mad_fixed_t) (((signed long long) (x) * (y)) >> MAD_F_SCALEBITS)) +# endif + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- Intel --------------------------------------------------------------- */ + +# elif defined(FPM_INTEL) + +/* + * This Intel version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("imull %3" \ + : "=a" (lo), "=d" (hi) \ + : "%a" (x), "rm" (y) \ + : "cc") + +# if defined(OPT_ACCURACY) +/* + * This gives best accuracy but is not very fast. + */ +# define MAD_F_MLA(hi, lo, x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + asm ("addl %2,%0\n\t" \ + "adcl %3,%1" \ + : "=rm" (lo), "=rm" (hi) \ + : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \ + : "cc"); \ + }) +# endif /* OPT_ACCURACY */ + +# if defined(OPT_ACCURACY) +/* + * Surprisingly, this is faster than SHRD followed by ADC. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed64hi_t __hi_; \ + mad_fixed64lo_t __lo_; \ + mad_fixed_t __result; \ + asm ("addl %4,%2\n\t" \ + "adcl %5,%3" \ + : "=rm" (__lo_), "=rm" (__hi_) \ + : "0" (lo), "1" (hi), \ + "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \ + : "cc"); \ + asm ("shrdl %3,%2,%1" \ + : "=rm" (__result) \ + : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# else +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("shrdl %3,%2,%1" \ + : "=rm" (__result) \ + : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# endif /* OPT_ACCURACY */ + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- ARM ----------------------------------------------------------------- */ + +# elif defined(FPM_ARM) + +/* + * This ARM V4 version is as accurate as FPM_64BIT but much faster. The + * least significant bit is properly rounded at no CPU cycle cost! + */ +# if 1 +/* + * There's a bug somewhere, possibly in the compiler, that sometimes makes + * this necessary instead of the default implementation via MAD_F_MLX and + * mad_f_scale64. It may be related to the use (or lack) of + * -finline-functions and/or -fstrength-reduce. + * + * This is also apparently faster than MAD_F_MLX/mad_f_scale64. + */ +# define mad_f_mul(x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + mad_fixed_t __result; \ + asm ("smull %0, %1, %3, %4\n\t" \ + "movs %0, %0, lsr %5\n\t" \ + "adc %2, %0, %1, lsl %6" \ + : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ + : "%r" (x), "r" (y), \ + "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# endif + +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("smull %0, %1, %2, %3" \ + : "=&r" (lo), "=&r" (hi) \ + : "%r" (x), "r" (y)) + +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("smlal %0, %1, %2, %3" \ + : "+r" (lo), "+r" (hi) \ + : "%r" (x), "r" (y)) + +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("movs %0, %1, lsr %3\n\t" \ + "adc %0, %0, %2, lsl %4" \ + : "=r" (__result) \ + : "r" (lo), "r" (hi), \ + "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- MIPS ---------------------------------------------------------------- */ + +# elif defined(FPM_MIPS) + +/* + * This MIPS version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("mult %2,%3" \ + : "=l" (lo), "=h" (hi) \ + : "%r" (x), "r" (y)) + +# if defined(HAVE_MADD_ASM) +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("madd %2,%3" \ + : "+l" (lo), "+h" (hi) \ + : "%r" (x), "r" (y)) +# elif defined(HAVE_MADD16_ASM) +/* + * This loses significant accuracy due to the 16-bit integer limit in the + * multiply/accumulate instruction. + */ +# define MAD_F_ML0(hi, lo, x, y) \ + asm ("mult %2,%3" \ + : "=l" (lo), "=h" (hi) \ + : "%r" ((x) >> 12), "r" ((y) >> 16)) +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("madd16 %2,%3" \ + : "+l" (lo), "+h" (hi) \ + : "%r" ((x) >> 12), "r" ((y) >> 16)) +# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) +# endif + +# if defined(OPT_SPEED) +# define mad_f_scale64(hi, lo) \ + ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS))) +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* --- SPARC --------------------------------------------------------------- */ + +# elif defined(FPM_SPARC) + +/* + * This SPARC V8 version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("smul %2, %3, %0\n\t" \ + "rd %%y, %1" \ + : "=r" (lo), "=r" (hi) \ + : "%r" (x), "rI" (y)) + +/* --- PowerPC ------------------------------------------------------------- */ + +# elif defined(FPM_PPC) + +/* + * This PowerPC version is tuned for the 4xx embedded processors. It is + * effectively a tuned version of FPM_64BIT. It is a little faster and just + * as accurate. The disposition of the least significant bit depends on + * OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("mulhw %1, %2, %3\n\t" \ + "mullw %0, %2, %3" \ + : "=&r" (lo), "=&r" (hi) \ + : "%r" (x), "r" (y)) + +# define MAD_F_MLA(hi, lo, x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + asm ("addc %0, %2, %3\n\t" \ + "adde %1, %4, %5" \ + : "=r" (lo), "=r" (hi) \ + : "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \ + }) + +# if defined(OPT_ACCURACY) +/* + * This is accurate and ~2 - 2.5 times slower than the unrounded version. + * + * The __volatile__ improves the generated code by another 5% (fewer spills + * to memory); eventually they should be removed. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + mad_fixed64hi_t __hi_; \ + mad_fixed64lo_t __lo_; \ + asm __volatile__ ("addc %0, %2, %4\n\t" \ + "addze %1, %3" \ + : "=r" (__lo_), "=r" (__hi_) \ + : "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \ + asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \ + "rlwimi %0, %1,32-%3,%3,31" \ + : "=&r" (__result) \ + : "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \ + __result; \ + }) +# else +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \ + "rlwimi %0, %1,32-%3,%3,31" \ + : "=r" (__result) \ + : "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \ + __result; \ + }) +# endif /* OPT_ACCURACY */ + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- Default ------------------------------------------------------------- */ + +# elif defined(FPM_DEFAULT) + +/* + * This version is the most portable but it loses significant accuracy. + * Furthermore, accuracy is biased against the second argument, so care + * should be taken when ordering operands. + * + * The scale factors are constant as this is not used with SSO. + * + * Pre-rounding is required to stay within the limits of compliance. + */ +# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ + (((y) + (1L << 15)) >> 16)) + +/* ------------------------------------------------------------------------- */ + +# else +# error "no FPM selected" +# endif + +/* default implementations */ + +# if !defined(mad_f_mul) +# define mad_f_mul(x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + mad_f_scale64(__hi, __lo); \ + }) +# endif + +# if !defined(MAD_F_MLA) +# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y))) +# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y))) +# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) +# endif + +# if !defined(MAD_F_ML0) +# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y)) +# endif + +# if !defined(MAD_F_MLZ) +# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo)) +# endif + +# if !defined(mad_f_scale64) +# if defined(OPT_ACCURACY) +# define mad_f_scale64(hi, lo) \ + ((((mad_fixed_t) \ + (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \ + ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1) +# else +# define mad_f_scale64(hi, lo) \ + ((mad_fixed_t) \ + (((hi) << (32 - MAD_F_SCALEBITS)) | \ + ((lo) >> MAD_F_SCALEBITS))) +# endif +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* miscellaneous C routines */ + +mad_fixed_t mad_f_abs(mad_fixed_t); + +# endif diff --git a/core/multimedia/opieplayer/libmad/frame.c b/core/multimedia/opieplayer/libmad/frame.c new file mode 100644 index 0000000..4ebb80c --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/frame.c @@ -0,0 +1,499 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# include + +# include "bit.h" +# include "stream.h" +# include "frame.h" +# include "timer.h" +# include "layer12.h" +# include "layer3.h" + +static +unsigned long const bitrate_table[5][15] = { + /* MPEG-1 */ + { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */ + 256000, 288000, 320000, 352000, 384000, 416000, 448000 }, + { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */ + 128000, 160000, 192000, 224000, 256000, 320000, 384000 }, + { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */ + 112000, 128000, 160000, 192000, 224000, 256000, 320000 }, + + /* MPEG-2 LSF */ + { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */ + 128000, 144000, 160000, 176000, 192000, 224000, 256000 }, + { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */ + 64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */ +}; + +static +unsigned int const samplerate_table[3] = { 44100, 48000, 32000 }; + +static +int (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = { + mad_layer_I, + mad_layer_II, + mad_layer_III +}; + +/* + * NAME: header->init() + * DESCRIPTION: initialize header struct + */ +void mad_header_init(struct mad_header *header) +{ + header->layer = 0; + header->mode = 0; + header->mode_extension = 0; + header->emphasis = 0; + + header->bitrate = 0; + header->samplerate = 0; + + header->crc_check = 0; + header->crc_target = 0; + + header->flags = 0; + header->private_bits = 0; + + header->duration = mad_timer_zero; +} + +/* + * NAME: frame->init() + * DESCRIPTION: initialize frame struct + */ +void mad_frame_init(struct mad_frame *frame) +{ + mad_header_init(&frame->header); + + frame->options = 0; + + frame->overlap = 0; + mad_frame_mute(frame); +} + +/* + * NAME: frame->finish() + * DESCRIPTION: deallocate any dynamic memory associated with frame + */ +void mad_frame_finish(struct mad_frame *frame) +{ + mad_header_finish(&frame->header); + + if (frame->overlap) { + free(frame->overlap); + frame->overlap = 0; + } +} + +/* + * NAME: decode_header() + * DESCRIPTION: read header data and following CRC word + */ +static +int decode_header(struct mad_header *header, struct mad_stream *stream) +{ + unsigned int index; + + header->flags = 0; + header->private_bits = 0; + + /* header() */ + + /* syncword */ + mad_bit_skip(&stream->ptr, 11); + + /* MPEG 2.5 indicator (really part of syncword) */ + if (mad_bit_read(&stream->ptr, 1) == 0) + header->flags |= MAD_FLAG_MPEG_2_5_EXT; + + /* ID */ + if (mad_bit_read(&stream->ptr, 1) == 0) + header->flags |= MAD_FLAG_LSF_EXT; + else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) { + stream->error = MAD_ERROR_LOSTSYNC; + return -1; + } + + /* layer */ + header->layer = 4 - mad_bit_read(&stream->ptr, 2); + + if (header->layer == 4) { + stream->error = MAD_ERROR_BADLAYER; + return -1; + } + + /* protection_bit */ + if (mad_bit_read(&stream->ptr, 1) == 0) { + header->flags |= MAD_FLAG_PROTECTION; + header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff); + } + + /* bitrate_index */ + index = mad_bit_read(&stream->ptr, 4); + + if (index == 15) { + stream->error = MAD_ERROR_BADBITRATE; + return -1; + } + + if (header->flags & MAD_FLAG_LSF_EXT) + header->bitrate = bitrate_table[3 + (header->layer >> 1)][index]; + else + header->bitrate = bitrate_table[header->layer - 1][index]; + + /* sampling_frequency */ + index = mad_bit_read(&stream->ptr, 2); + + if (index == 3) { + stream->error = MAD_ERROR_BADSAMPLERATE; + return -1; + } + + header->samplerate = samplerate_table[index]; + + if (header->flags & MAD_FLAG_LSF_EXT) { + header->samplerate /= 2; + + if (header->flags & MAD_FLAG_MPEG_2_5_EXT) + header->samplerate /= 2; + } + + /* padding_bit */ + if (mad_bit_read(&stream->ptr, 1)) + header->flags |= MAD_FLAG_PADDING; + + /* private_bit */ + if (mad_bit_read(&stream->ptr, 1)) + header->private_bits |= MAD_PRIVATE_HEADER; + + /* mode */ + header->mode = 3 - mad_bit_read(&stream->ptr, 2); + + /* mode_extension */ + header->mode_extension = mad_bit_read(&stream->ptr, 2); + + /* copyright */ + if (mad_bit_read(&stream->ptr, 1)) + header->flags |= MAD_FLAG_COPYRIGHT; + + /* original/copy */ + if (mad_bit_read(&stream->ptr, 1)) + header->flags |= MAD_FLAG_ORIGINAL; + + /* emphasis */ + header->emphasis = mad_bit_read(&stream->ptr, 2); + + if (header->emphasis == 2) { + stream->error = MAD_ERROR_BADEMPHASIS; + return -1; + } + + /* error_check() */ + + /* crc_check */ + if (header->flags & MAD_FLAG_PROTECTION) + header->crc_target = mad_bit_read(&stream->ptr, 16); + + return 0; +} + +/* + * NAME: free_bitrate() + * DESCRIPTION: attempt to discover the bitstream's free bitrate + */ +static +int free_bitrate(struct mad_stream *stream, struct mad_header const *header) +{ + struct mad_bitptr keep_ptr; + unsigned long rate = 0; + unsigned int pad_slot, slots_per_frame; + unsigned char const *ptr = 0; + + keep_ptr = stream->ptr; + + pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; + slots_per_frame = (header->layer == MAD_LAYER_III && + (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; + + while (mad_stream_sync(stream) == 0) { + struct mad_stream peek_stream; + struct mad_header peek_header; + + peek_stream = *stream; + peek_header = *header; + + if (decode_header(&peek_header, &peek_stream) == 0 && + peek_header.layer == header->layer && + peek_header.samplerate == header->samplerate) { + unsigned int N; + + ptr = mad_bit_nextbyte(&stream->ptr); + + N = ptr - stream->this_frame; + + if (header->layer == MAD_LAYER_I) { + rate = (unsigned long) header->samplerate * + (N - 4 * pad_slot + 4) / 48 / 1000; + } + else { + rate = (unsigned long) header->samplerate * + (N - pad_slot + 1) / slots_per_frame / 1000; + } + + if (rate >= 8) + break; + } + + mad_bit_skip(&stream->ptr, 8); + } + + stream->ptr = keep_ptr; + + if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) { + stream->error = MAD_ERROR_LOSTSYNC; + return -1; + } + + stream->freerate = rate * 1000; + +# if 0 && defined(DEBUG) + fprintf(stderr, "free bitrate == %lu\n", stream->freerate); +# endif + + return 0; +} + +/* + * NAME: header->decode() + * DESCRIPTION: read the next frame header from the stream + */ +int mad_header_decode(struct mad_header *header, struct mad_stream *stream) +{ + register unsigned char const *ptr, *end; + unsigned int pad_slot, N; + + ptr = stream->next_frame; + end = stream->bufend; + + if (ptr == 0) { + stream->error = MAD_ERROR_BUFPTR; + goto fail; + } + + /* stream skip */ + if (stream->skiplen) { + if (!stream->sync) + ptr = stream->this_frame; + + if (end - ptr < stream->skiplen) { + stream->skiplen -= end - ptr; + stream->next_frame = end; + + stream->error = MAD_ERROR_BUFLEN; + goto fail; + } + + ptr += stream->skiplen; + stream->skiplen = 0; + + stream->sync = 1; + } + + sync: + /* synchronize */ + if (stream->sync) { + if (end - ptr < MAD_BUFFER_GUARD) { + stream->next_frame = ptr; + + stream->error = MAD_ERROR_BUFLEN; + goto fail; + } + else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { + /* mark point where frame sync word was expected */ + stream->this_frame = ptr; + stream->next_frame = ptr + 1; + + stream->error = MAD_ERROR_LOSTSYNC; + goto fail; + } + } + else { + mad_bit_init(&stream->ptr, ptr); + + if (mad_stream_sync(stream) == -1) { + if (end - stream->next_frame >= MAD_BUFFER_GUARD) + stream->next_frame = end - MAD_BUFFER_GUARD; + + stream->error = MAD_ERROR_BUFLEN; + goto fail; + } + + ptr = mad_bit_nextbyte(&stream->ptr); + } + + /* begin processing */ + stream->this_frame = ptr; + stream->next_frame = ptr + 1; /* possibly bogus sync word */ + + mad_bit_init(&stream->ptr, stream->this_frame); + + if (decode_header(header, stream) == -1) + goto fail; + + /* calculate frame duration */ + mad_timer_set(&header->duration, 0, + 32 * MAD_NSBSAMPLES(header), header->samplerate); + + /* calculate free bit rate */ + if (header->bitrate == 0) { + if ((!stream->sync || !stream->freerate) && + free_bitrate(stream, header) == -1) + goto fail; + + header->bitrate = stream->freerate; + header->flags |= MAD_FLAG_FREEFORMAT; + } + + /* calculate beginning of next frame */ + pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; + + if (header->layer == MAD_LAYER_I) + N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4; + else { + unsigned int slots_per_frame; + + slots_per_frame = (header->layer == MAD_LAYER_III && + (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; + + N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot; + } + + /* verify there is enough data left in buffer to decode this frame */ + if (N + MAD_BUFFER_GUARD > end - stream->this_frame) { + stream->next_frame = stream->this_frame; + + stream->error = MAD_ERROR_BUFLEN; + goto fail; + } + + stream->next_frame = stream->this_frame + N; + + if (!stream->sync) { + /* check that a valid frame header follows this frame */ + + ptr = stream->next_frame; + if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { + ptr = stream->next_frame = stream->this_frame + 1; + goto sync; + } + + stream->sync = 1; + } + + header->flags |= MAD_FLAG_INCOMPLETE; + + return 0; + + fail: + stream->sync = 0; + + return -1; +} + +/* + * NAME: frame->decode() + * DESCRIPTION: decode a single frame from a bitstream + */ +int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream) +{ + frame->options = stream->options; + + /* header() */ + /* error_check() */ + + if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) && + mad_header_decode(&frame->header, stream) == -1) + goto fail; + + /* audio_data() */ + + frame->header.flags &= ~MAD_FLAG_INCOMPLETE; + + if (decoder_table[frame->header.layer - 1](stream, frame) == -1) { + if (!MAD_RECOVERABLE(stream->error)) + stream->next_frame = stream->this_frame; + + goto fail; + } + + /* ancillary_data() */ + + if (frame->header.layer != MAD_LAYER_III) { + struct mad_bitptr next_frame; + + mad_bit_init(&next_frame, stream->next_frame); + + stream->anc_ptr = stream->ptr; + stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame); + + mad_bit_finish(&next_frame); + } + + return 0; + + fail: + stream->anc_bitlen = 0; + return -1; +} + +/* + * NAME: frame->mute() + * DESCRIPTION: zero all subband values so the frame becomes silent + */ +void mad_frame_mute(struct mad_frame *frame) +{ + unsigned int s, sb; + + for (s = 0; s < 36; ++s) { + for (sb = 0; sb < 32; ++sb) { + frame->sbsample[0][s][sb] = + frame->sbsample[1][s][sb] = 0; + } + } + + if (frame->overlap) { + for (s = 0; s < 18; ++s) { + for (sb = 0; sb < 32; ++sb) { + (*frame->overlap)[0][sb][s] = + (*frame->overlap)[1][sb][s] = 0; + } + } + } +} diff --git a/core/multimedia/opieplayer/libmad/frame.h b/core/multimedia/opieplayer/libmad/frame.h new file mode 100644 index 0000000..e88d0c8 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/frame.h @@ -0,0 +1,115 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_FRAME_H +# define LIBMAD_FRAME_H + +# include "fixed.h" +# include "timer.h" +# include "stream.h" + +enum mad_layer { + MAD_LAYER_I = 1, /* Layer I */ + MAD_LAYER_II = 2, /* Layer II */ + MAD_LAYER_III = 3 /* Layer III */ +}; + +enum mad_mode { + MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ + MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ + MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ + MAD_MODE_STEREO = 3 /* normal LR stereo */ +}; + +enum mad_emphasis { + MAD_EMPHASIS_NONE = 0, /* no emphasis */ + MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ + MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */ +}; + +struct mad_frame { + struct mad_header { + enum mad_layer layer; /* audio layer (1, 2, or 3) */ + enum mad_mode mode; /* channel mode (see above) */ + int mode_extension; /* additional mode info */ + enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ + + unsigned long bitrate; /* stream bitrate (bps) */ + unsigned int samplerate; /* sampling frequency (Hz) */ + + unsigned short crc_check; /* frame CRC accumulator */ + unsigned short crc_target; /* final target CRC checksum */ + + int flags; /* flags (see below) */ + int private_bits; /* private bits (see below) */ + + mad_timer_t duration; /* audio playing time of frame */ + } header; + + int options; /* decoding options (from stream) */ + + mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ + mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */ +}; + +# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) +# define MAD_NSBSAMPLES(header) \ + ((header)->layer == MAD_LAYER_I ? 12 : \ + (((header)->layer == MAD_LAYER_III && \ + ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) + +enum { + MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ + MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ + + MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ + MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ + MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ + MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ + + MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ + MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ + MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ + + MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ + MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ + MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ +}; + +enum { + MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ + MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ +}; + +void mad_header_init(struct mad_header *); + +# define mad_header_finish(header) /* nothing */ + +int mad_header_decode(struct mad_header *, struct mad_stream *); + +void mad_frame_init(struct mad_frame *); +void mad_frame_finish(struct mad_frame *); + +int mad_frame_decode(struct mad_frame *, struct mad_stream *); + +void mad_frame_mute(struct mad_frame *); + +# endif diff --git a/core/multimedia/opieplayer/libmad/huffman.c b/core/multimedia/opieplayer/libmad/huffman.c new file mode 100644 index 0000000..8ec9499 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/huffman.c @@ -0,0 +1,3087 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# include "huffman.h" + +/* + * These are the Huffman code words for Layer III. + * The data for these tables are derived from Table B.7 of ISO/IEC 11172-3. + * + * These tables support decoding up to 4 Huffman code bits at a time. + */ + +# define V(v, w, x, y, hlen) { { 1, hlen, v, w, x, y } } +# define PTR(offs, bits) { ptr: { 0, bits, offs } } + +static +union huffquad const hufftabA[] = { + /* 0000 */ PTR(16, 2), + /* 0001 */ PTR(20, 2), + /* 0010 */ PTR(24, 1), + /* 0011 */ PTR(26, 1), + /* 0100 */ V(0, 0, 1, 0, 4), + /* 0101 */ V(0, 0, 0, 1, 4), + /* 0110 */ V(0, 1, 0, 0, 4), + /* 0111 */ V(1, 0, 0, 0, 4), + /* 1000 */ V(0, 0, 0, 0, 1), + /* 1001 */ V(0, 0, 0, 0, 1), + /* 1010 */ V(0, 0, 0, 0, 1), + /* 1011 */ V(0, 0, 0, 0, 1), + /* 1100 */ V(0, 0, 0, 0, 1), + /* 1101 */ V(0, 0, 0, 0, 1), + /* 1110 */ V(0, 0, 0, 0, 1), + /* 1111 */ V(0, 0, 0, 0, 1), + + /* 0000 ... */ + /* 00 */ V(1, 0, 1, 1, 2), /* 16 */ + /* 01 */ V(1, 1, 1, 1, 2), + /* 10 */ V(1, 1, 0, 1, 2), + /* 11 */ V(1, 1, 1, 0, 2), + + /* 0001 ... */ + /* 00 */ V(0, 1, 1, 1, 2), /* 20 */ + /* 01 */ V(0, 1, 0, 1, 2), + /* 10 */ V(1, 0, 0, 1, 1), + /* 11 */ V(1, 0, 0, 1, 1), + + /* 0010 ... */ + /* 0 */ V(0, 1, 1, 0, 1), /* 24 */ + /* 1 */ V(0, 0, 1, 1, 1), + + /* 0011 ... */ + /* 0 */ V(1, 0, 1, 0, 1), /* 26 */ + /* 1 */ V(1, 1, 0, 0, 1) +}; + +static +union huffquad const hufftabB[] = { + /* 0000 */ V(1, 1, 1, 1, 4), + /* 0001 */ V(1, 1, 1, 0, 4), + /* 0010 */ V(1, 1, 0, 1, 4), + /* 0011 */ V(1, 1, 0, 0, 4), + /* 0100 */ V(1, 0, 1, 1, 4), + /* 0101 */ V(1, 0, 1, 0, 4), + /* 0110 */ V(1, 0, 0, 1, 4), + /* 0111 */ V(1, 0, 0, 0, 4), + /* 1000 */ V(0, 1, 1, 1, 4), + /* 1001 */ V(0, 1, 1, 0, 4), + /* 1010 */ V(0, 1, 0, 1, 4), + /* 1011 */ V(0, 1, 0, 0, 4), + /* 1100 */ V(0, 0, 1, 1, 4), + /* 1101 */ V(0, 0, 1, 0, 4), + /* 1110 */ V(0, 0, 0, 1, 4), + /* 1111 */ V(0, 0, 0, 0, 4) +}; + +# undef V +# undef PTR + +# define V(x, y, hlen) { { 1, hlen, x, y } } +# define PTR(offs, bits) { ptr: { 0, bits, offs } } + +static +union huffpair const hufftab0[] = { + /* */ V(0, 0, 0) +}; + +static +union huffpair const hufftab1[] = { + /* 000 */ V(1, 1, 3), + /* 001 */ V(0, 1, 3), + /* 010 */ V(1, 0, 2), + /* 011 */ V(1, 0, 2), + /* 100 */ V(0, 0, 1), + /* 101 */ V(0, 0, 1), + /* 110 */ V(0, 0, 1), + /* 111 */ V(0, 0, 1) +}; + +static +union huffpair const hufftab2[] = { + /* 000 */ PTR(8, 3), + /* 001 */ V(1, 1, 3), + /* 010 */ V(0, 1, 3), + /* 011 */ V(1, 0, 3), + /* 100 */ V(0, 0, 1), + /* 101 */ V(0, 0, 1), + /* 110 */ V(0, 0, 1), + /* 111 */ V(0, 0, 1), + + /* 000 ... */ + /* 000 */ V(2, 2, 3), /* 8 */ + /* 001 */ V(0, 2, 3), + /* 010 */ V(1, 2, 2), + /* 011 */ V(1, 2, 2), + /* 100 */ V(2, 1, 2), + /* 101 */ V(2, 1, 2), + /* 110 */ V(2, 0, 2), + /* 111 */ V(2, 0, 2) +}; + +static +union huffpair const hufftab3[] = { + /* 000 */ PTR(8, 3), + /* 001 */ V(1, 0, 3), + /* 010 */ V(1, 1, 2), + /* 011 */ V(1, 1, 2), + /* 100 */ V(0, 1, 2), + /* 101 */ V(0, 1, 2), + /* 110 */ V(0, 0, 2), + /* 111 */ V(0, 0, 2), + + /* 000 ... */ + /* 000 */ V(2, 2, 3), /* 8 */ + /* 001 */ V(0, 2, 3), + /* 010 */ V(1, 2, 2), + /* 011 */ V(1, 2, 2), + /* 100 */ V(2, 1, 2), + /* 101 */ V(2, 1, 2), + /* 110 */ V(2, 0, 2), + /* 111 */ V(2, 0, 2) +}; + +static +union huffpair const hufftab5[] = { + /* 000 */ PTR(8, 4), + /* 001 */ V(1, 1, 3), + /* 010 */ V(0, 1, 3), + /* 011 */ V(1, 0, 3), + /* 100 */ V(0, 0, 1), + /* 101 */ V(0, 0, 1), + /* 110 */ V(0, 0, 1), + /* 111 */ V(0, 0, 1), + + /* 000 ... */ + /* 0000 */ PTR(24, 1), /* 8 */ + /* 0001 */ V(3, 2, 4), + /* 0010 */ V(3, 1, 3), + /* 0011 */ V(3, 1, 3), + /* 0100 */ V(1, 3, 4), + /* 0101 */ V(0, 3, 4), + /* 0110 */ V(3, 0, 4), + /* 0111 */ V(2, 2, 4), + /* 1000 */ V(1, 2, 3), + /* 1001 */ V(1, 2, 3), + /* 1010 */ V(2, 1, 3), + /* 1011 */ V(2, 1, 3), + /* 1100 */ V(0, 2, 3), + /* 1101 */ V(0, 2, 3), + /* 1110 */ V(2, 0, 3), + /* 1111 */ V(2, 0, 3), + + /* 000 0000 ... */ + /* 0 */ V(3, 3, 1), /* 24 */ + /* 1 */ V(2, 3, 1) +}; + +static +union huffpair const hufftab6[] = { + /* 0000 */ PTR(16, 3), + /* 0001 */ PTR(24, 1), + /* 0010 */ PTR(26, 1), + /* 0011 */ V(1, 2, 4), + /* 0100 */ V(2, 1, 4), + /* 0101 */ V(2, 0, 4), + /* 0110 */ V(0, 1, 3), + /* 0111 */ V(0, 1, 3), + /* 1000 */ V(1, 1, 2), + /* 1001 */ V(1, 1, 2), + /* 1010 */ V(1, 1, 2), + /* 1011 */ V(1, 1, 2), + /* 1100 */ V(1, 0, 3), + /* 1101 */ V(1, 0, 3), + /* 1110 */ V(0, 0, 3), + /* 1111 */ V(0, 0, 3), + + /* 0000 ... */ + /* 000 */ V(3, 3, 3), /* 16 */ + /* 001 */ V(0, 3, 3), + /* 010 */ V(2, 3, 2), + /* 011 */ V(2, 3, 2), + /* 100 */ V(3, 2, 2), + /* 101 */ V(3, 2, 2), + /* 110 */ V(3, 0, 2), + /* 111 */ V(3, 0, 2), + + /* 0001 ... */ + /* 0 */ V(1, 3, 1), /* 24 */ + /* 1 */ V(3, 1, 1), + + /* 0010 ... */ + /* 0 */ V(2, 2, 1), /* 26 */ + /* 1 */ V(0, 2, 1) +}; + +static +union huffpair const hufftab7[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 2), + /* 0011 */ V(1, 1, 4), + /* 0100 */ V(0, 1, 3), + /* 0101 */ V(0, 1, 3), + /* 0110 */ V(1, 0, 3), + /* 0111 */ V(1, 0, 3), + /* 1000 */ V(0, 0, 1), + /* 1001 */ V(0, 0, 1), + /* 1010 */ V(0, 0, 1), + /* 1011 */ V(0, 0, 1), + /* 1100 */ V(0, 0, 1), + /* 1101 */ V(0, 0, 1), + /* 1110 */ V(0, 0, 1), + /* 1111 */ V(0, 0, 1), + + /* 0000 ... */ + /* 0000 */ PTR(52, 2), /* 16 */ + /* 0001 */ PTR(56, 1), + /* 0010 */ PTR(58, 1), + /* 0011 */ V(1, 5, 4), + /* 0100 */ V(5, 1, 4), + /* 0101 */ PTR(60, 1), + /* 0110 */ V(5, 0, 4), + /* 0111 */ PTR(62, 1), + /* 1000 */ V(2, 4, 4), + /* 1001 */ V(4, 2, 4), + /* 1010 */ V(1, 4, 3), + /* 1011 */ V(1, 4, 3), + /* 1100 */ V(4, 1, 3), + /* 1101 */ V(4, 1, 3), + /* 1110 */ V(4, 0, 3), + /* 1111 */ V(4, 0, 3), + + /* 0001 ... */ + /* 0000 */ V(0, 4, 4), /* 32 */ + /* 0001 */ V(2, 3, 4), + /* 0010 */ V(3, 2, 4), + /* 0011 */ V(0, 3, 4), + /* 0100 */ V(1, 3, 3), + /* 0101 */ V(1, 3, 3), + /* 0110 */ V(3, 1, 3), + /* 0111 */ V(3, 1, 3), + /* 1000 */ V(3, 0, 3), + /* 1001 */ V(3, 0, 3), + /* 1010 */ V(2, 2, 3), + /* 1011 */ V(2, 2, 3), + /* 1100 */ V(1, 2, 2), + /* 1101 */ V(1, 2, 2), + /* 1110 */ V(1, 2, 2), + /* 1111 */ V(1, 2, 2), + + /* 0010 ... */ + /* 00 */ V(2, 1, 1), /* 48 */ + /* 01 */ V(2, 1, 1), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 00 */ V(5, 5, 2), /* 52 */ + /* 01 */ V(4, 5, 2), + /* 10 */ V(5, 4, 2), + /* 11 */ V(5, 3, 2), + + /* 0000 0001 ... */ + /* 0 */ V(3, 5, 1), /* 56 */ + /* 1 */ V(4, 4, 1), + + /* 0000 0010 ... */ + /* 0 */ V(2, 5, 1), /* 58 */ + /* 1 */ V(5, 2, 1), + + /* 0000 0101 ... */ + /* 0 */ V(0, 5, 1), /* 60 */ + /* 1 */ V(3, 4, 1), + + /* 0000 0111 ... */ + /* 0 */ V(4, 3, 1), /* 62 */ + /* 1 */ V(3, 3, 1) +}; + +# if 0 +/* this version saves 8 entries (16 bytes) at the expense of + an extra lookup in 4 out of 36 cases */ +static +union huffpair const hufftab8[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 2), + /* 0010 */ V(1, 2, 4), + /* 0011 */ V(2, 1, 4), + /* 0100 */ V(1, 1, 2), + /* 0101 */ V(1, 1, 2), + /* 0110 */ V(1, 1, 2), + /* 0111 */ V(1, 1, 2), + /* 1000 */ V(0, 1, 3), + /* 1001 */ V(0, 1, 3), + /* 1010 */ V(1, 0, 3), + /* 1011 */ V(1, 0, 3), + /* 1100 */ V(0, 0, 2), + /* 1101 */ V(0, 0, 2), + /* 1110 */ V(0, 0, 2), + /* 1111 */ V(0, 0, 2), + + /* 0000 ... */ + /* 0000 */ PTR(36, 3), /* 16 */ + /* 0001 */ PTR(44, 2), + /* 0010 */ PTR(48, 1), + /* 0011 */ V(1, 5, 4), + /* 0100 */ V(5, 1, 4), + /* 0101 */ PTR(50, 1), + /* 0110 */ PTR(52, 1), + /* 0111 */ V(2, 4, 4), + /* 1000 */ V(4, 2, 4), + /* 1001 */ V(1, 4, 4), + /* 1010 */ V(4, 1, 3), + /* 1011 */ V(4, 1, 3), + /* 1100 */ V(0, 4, 4), + /* 1101 */ V(4, 0, 4), + /* 1110 */ V(2, 3, 4), + /* 1111 */ V(3, 2, 4), + + /* 0001 ... */ + /* 00 */ PTR(54, 2), /* 32 */ + /* 01 */ V(2, 2, 2), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 000 */ V(5, 5, 3), /* 36 */ + /* 001 */ V(5, 4, 3), + /* 010 */ V(4, 5, 2), + /* 011 */ V(4, 5, 2), + /* 100 */ V(5, 3, 1), + /* 101 */ V(5, 3, 1), + /* 110 */ V(5, 3, 1), + /* 111 */ V(5, 3, 1), + + /* 0000 0001 ... */ + /* 00 */ V(3, 5, 2), /* 44 */ + /* 01 */ V(4, 4, 2), + /* 10 */ V(2, 5, 1), + /* 11 */ V(2, 5, 1), + + /* 0000 0010 ... */ + /* 0 */ V(5, 2, 1), /* 48 */ + /* 1 */ V(0, 5, 1), + + /* 0000 0101 ... */ + /* 0 */ V(3, 4, 1), /* 50 */ + /* 1 */ V(4, 3, 1), + + /* 0000 0110 ... */ + /* 0 */ V(5, 0, 1), /* 52 */ + /* 1 */ V(3, 3, 1), + + /* 0001 00 ... */ + /* 00 */ V(1, 3, 2), /* 54 */ + /* 01 */ V(3, 1, 2), + /* 10 */ V(0, 3, 2), + /* 11 */ V(3, 0, 2), +}; +# else +static +union huffpair const hufftab8[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ V(1, 2, 4), + /* 0011 */ V(2, 1, 4), + /* 0100 */ V(1, 1, 2), + /* 0101 */ V(1, 1, 2), + /* 0110 */ V(1, 1, 2), + /* 0111 */ V(1, 1, 2), + /* 1000 */ V(0, 1, 3), + /* 1001 */ V(0, 1, 3), + /* 1010 */ V(1, 0, 3), + /* 1011 */ V(1, 0, 3), + /* 1100 */ V(0, 0, 2), + /* 1101 */ V(0, 0, 2), + /* 1110 */ V(0, 0, 2), + /* 1111 */ V(0, 0, 2), + + /* 0000 ... */ + /* 0000 */ PTR(48, 3), /* 16 */ + /* 0001 */ PTR(56, 2), + /* 0010 */ PTR(60, 1), + /* 0011 */ V(1, 5, 4), + /* 0100 */ V(5, 1, 4), + /* 0101 */ PTR(62, 1), + /* 0110 */ PTR(64, 1), + /* 0111 */ V(2, 4, 4), + /* 1000 */ V(4, 2, 4), + /* 1001 */ V(1, 4, 4), + /* 1010 */ V(4, 1, 3), + /* 1011 */ V(4, 1, 3), + /* 1100 */ V(0, 4, 4), + /* 1101 */ V(4, 0, 4), + /* 1110 */ V(2, 3, 4), + /* 1111 */ V(3, 2, 4), + + /* 0001 ... */ + /* 0000 */ V(1, 3, 4), /* 32 */ + /* 0001 */ V(3, 1, 4), + /* 0010 */ V(0, 3, 4), + /* 0011 */ V(3, 0, 4), + /* 0100 */ V(2, 2, 2), + /* 0101 */ V(2, 2, 2), + /* 0110 */ V(2, 2, 2), + /* 0111 */ V(2, 2, 2), + /* 1000 */ V(0, 2, 2), + /* 1001 */ V(0, 2, 2), + /* 1010 */ V(0, 2, 2), + /* 1011 */ V(0, 2, 2), + /* 1100 */ V(2, 0, 2), + /* 1101 */ V(2, 0, 2), + /* 1110 */ V(2, 0, 2), + /* 1111 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 000 */ V(5, 5, 3), /* 48 */ + /* 001 */ V(5, 4, 3), + /* 010 */ V(4, 5, 2), + /* 011 */ V(4, 5, 2), + /* 100 */ V(5, 3, 1), + /* 101 */ V(5, 3, 1), + /* 110 */ V(5, 3, 1), + /* 111 */ V(5, 3, 1), + + /* 0000 0001 ... */ + /* 00 */ V(3, 5, 2), /* 56 */ + /* 01 */ V(4, 4, 2), + /* 10 */ V(2, 5, 1), + /* 11 */ V(2, 5, 1), + + /* 0000 0010 ... */ + /* 0 */ V(5, 2, 1), /* 60 */ + /* 1 */ V(0, 5, 1), + + /* 0000 0101 ... */ + /* 0 */ V(3, 4, 1), /* 62 */ + /* 1 */ V(4, 3, 1), + + /* 0000 0110 ... */ + /* 0 */ V(5, 0, 1), /* 64 */ + /* 1 */ V(3, 3, 1) +}; +# endif + +static +union huffpair const hufftab9[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 3), + /* 0010 */ PTR(40, 2), + /* 0011 */ PTR(44, 2), + /* 0100 */ PTR(48, 1), + /* 0101 */ V(1, 2, 4), + /* 0110 */ V(2, 1, 4), + /* 0111 */ V(2, 0, 4), + /* 1000 */ V(1, 1, 3), + /* 1001 */ V(1, 1, 3), + /* 1010 */ V(0, 1, 3), + /* 1011 */ V(0, 1, 3), + /* 1100 */ V(1, 0, 3), + /* 1101 */ V(1, 0, 3), + /* 1110 */ V(0, 0, 3), + /* 1111 */ V(0, 0, 3), + + /* 0000 ... */ + /* 0000 */ PTR(50, 1), /* 16 */ + /* 0001 */ V(3, 5, 4), + /* 0010 */ V(5, 3, 4), + /* 0011 */ PTR(52, 1), + /* 0100 */ V(4, 4, 4), + /* 0101 */ V(2, 5, 4), + /* 0110 */ V(5, 2, 4), + /* 0111 */ V(1, 5, 4), + /* 1000 */ V(5, 1, 3), + /* 1001 */ V(5, 1, 3), + /* 1010 */ V(3, 4, 3), + /* 1011 */ V(3, 4, 3), + /* 1100 */ V(4, 3, 3), + /* 1101 */ V(4, 3, 3), + /* 1110 */ V(5, 0, 4), + /* 1111 */ V(0, 4, 4), + + /* 0001 ... */ + /* 000 */ V(2, 4, 3), /* 32 */ + /* 001 */ V(4, 2, 3), + /* 010 */ V(3, 3, 3), + /* 011 */ V(4, 0, 3), + /* 100 */ V(1, 4, 2), + /* 101 */ V(1, 4, 2), + /* 110 */ V(4, 1, 2), + /* 111 */ V(4, 1, 2), + + /* 0010 ... */ + /* 00 */ V(2, 3, 2), /* 40 */ + /* 01 */ V(3, 2, 2), + /* 10 */ V(1, 3, 1), + /* 11 */ V(1, 3, 1), + + /* 0011 ... */ + /* 00 */ V(3, 1, 1), /* 44 */ + /* 01 */ V(3, 1, 1), + /* 10 */ V(0, 3, 2), + /* 11 */ V(3, 0, 2), + + /* 0100 ... */ + /* 0 */ V(2, 2, 1), /* 48 */ + /* 1 */ V(0, 2, 1), + + /* 0000 0000 ... */ + /* 0 */ V(5, 5, 1), /* 50 */ + /* 1 */ V(4, 5, 1), + + /* 0000 0011 ... */ + /* 0 */ V(5, 4, 1), /* 52 */ + /* 1 */ V(0, 5, 1) +}; + +static +union huffpair const hufftab10[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 2), + /* 0011 */ V(1, 1, 4), + /* 0100 */ V(0, 1, 3), + /* 0101 */ V(0, 1, 3), + /* 0110 */ V(1, 0, 3), + /* 0111 */ V(1, 0, 3), + /* 1000 */ V(0, 0, 1), + /* 1001 */ V(0, 0, 1), + /* 1010 */ V(0, 0, 1), + /* 1011 */ V(0, 0, 1), + /* 1100 */ V(0, 0, 1), + /* 1101 */ V(0, 0, 1), + /* 1110 */ V(0, 0, 1), + /* 1111 */ V(0, 0, 1), + + /* 0000 ... */ + /* 0000 */ PTR(52, 3), /* 16 */ + /* 0001 */ PTR(60, 2), + /* 0010 */ PTR(64, 3), + /* 0011 */ PTR(72, 1), + /* 0100 */ PTR(74, 2), + /* 0101 */ PTR(78, 2), + /* 0110 */ PTR(82, 2), + /* 0111 */ V(1, 7, 4), + /* 1000 */ V(7, 1, 4), + /* 1001 */ PTR(86, 1), + /* 1010 */ PTR(88, 2), + /* 1011 */ PTR(92, 2), + /* 1100 */ V(1, 6, 4), + /* 1101 */ V(6, 1, 4), + /* 1110 */ V(6, 0, 4), + /* 1111 */ PTR(96, 1), + + /* 0001 ... */ + /* 0000 */ PTR(98, 1), /* 32 */ + /* 0001 */ PTR(100, 1), + /* 0010 */ V(1, 4, 4), + /* 0011 */ V(4, 1, 4), + /* 0100 */ V(4, 0, 4), + /* 0101 */ V(2, 3, 4), + /* 0110 */ V(3, 2, 4), + /* 0111 */ V(0, 3, 4), + /* 1000 */ V(1, 3, 3), + /* 1001 */ V(1, 3, 3), + /* 1010 */ V(3, 1, 3), + /* 1011 */ V(3, 1, 3), + /* 1100 */ V(3, 0, 3), + /* 1101 */ V(3, 0, 3), + /* 1110 */ V(2, 2, 3), + /* 1111 */ V(2, 2, 3), + + /* 0010 ... */ + /* 00 */ V(1, 2, 2), /* 48 */ + /* 01 */ V(2, 1, 2), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 000 */ V(7, 7, 3), /* 52 */ + /* 001 */ V(6, 7, 3), + /* 010 */ V(7, 6, 3), + /* 011 */ V(5, 7, 3), + /* 100 */ V(7, 5, 3), + /* 101 */ V(6, 6, 3), + /* 110 */ V(4, 7, 2), + /* 111 */ V(4, 7, 2), + + /* 0000 0001 ... */ + /* 00 */ V(7, 4, 2), /* 60 */ + /* 01 */ V(5, 6, 2), + /* 10 */ V(6, 5, 2), + /* 11 */ V(3, 7, 2), + + /* 0000 0010 ... */ + /* 000 */ V(7, 3, 2), /* 64 */ + /* 001 */ V(7, 3, 2), + /* 010 */ V(4, 6, 2), + /* 011 */ V(4, 6, 2), + /* 100 */ V(5, 5, 3), + /* 101 */ V(5, 4, 3), + /* 110 */ V(6, 3, 2), + /* 111 */ V(6, 3, 2), + + /* 0000 0011 ... */ + /* 0 */ V(2, 7, 1), /* 72 */ + /* 1 */ V(7, 2, 1), + + /* 0000 0100 ... */ + /* 00 */ V(6, 4, 2), /* 74 */ + /* 01 */ V(0, 7, 2), + /* 10 */ V(7, 0, 1), + /* 11 */ V(7, 0, 1), + + /* 0000 0101 ... */ + /* 00 */ V(6, 2, 1), /* 78 */ + /* 01 */ V(6, 2, 1), + /* 10 */ V(4, 5, 2), + /* 11 */ V(3, 5, 2), + + /* 0000 0110 ... */ + /* 00 */ V(0, 6, 1), /* 82 */ + /* 01 */ V(0, 6, 1), + /* 10 */ V(5, 3, 2), + /* 11 */ V(4, 4, 2), + + /* 0000 1001 ... */ + /* 0 */ V(3, 6, 1), /* 86 */ + /* 1 */ V(2, 6, 1), + + /* 0000 1010 ... */ + /* 00 */ V(2, 5, 2), /* 88 */ + /* 01 */ V(5, 2, 2), + /* 10 */ V(1, 5, 1), + /* 11 */ V(1, 5, 1), + + /* 0000 1011 ... */ + /* 00 */ V(5, 1, 1), /* 92 */ + /* 01 */ V(5, 1, 1), + /* 10 */ V(3, 4, 2), + /* 11 */ V(4, 3, 2), + + /* 0000 1111 ... */ + /* 0 */ V(0, 5, 1), /* 96 */ + /* 1 */ V(5, 0, 1), + + /* 0001 0000 ... */ + /* 0 */ V(2, 4, 1), /* 98 */ + /* 1 */ V(4, 2, 1), + + /* 0001 0001 ... */ + /* 0 */ V(3, 3, 1), /* 100 */ + /* 1 */ V(0, 4, 1) +}; + +static +union huffpair const hufftab11[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 3), + /* 0100 */ V(1, 2, 4), + /* 0101 */ PTR(72, 1), + /* 0110 */ V(1, 1, 3), + /* 0111 */ V(1, 1, 3), + /* 1000 */ V(0, 1, 3), + /* 1001 */ V(0, 1, 3), + /* 1010 */ V(1, 0, 3), + /* 1011 */ V(1, 0, 3), + /* 1100 */ V(0, 0, 2), + /* 1101 */ V(0, 0, 2), + /* 1110 */ V(0, 0, 2), + /* 1111 */ V(0, 0, 2), + + /* 0000 ... */ + /* 0000 */ PTR(74, 2), /* 16 */ + /* 0001 */ PTR(78, 3), + /* 0010 */ PTR(86, 2), + /* 0011 */ PTR(90, 1), + /* 0100 */ PTR(92, 2), + /* 0101 */ V(2, 7, 4), + /* 0110 */ V(7, 2, 4), + /* 0111 */ PTR(96, 1), + /* 1000 */ V(7, 1, 3), + /* 1001 */ V(7, 1, 3), + /* 1010 */ V(1, 7, 4), + /* 1011 */ V(7, 0, 4), + /* 1100 */ V(3, 6, 4), + /* 1101 */ V(6, 3, 4), + /* 1110 */ V(6, 0, 4), + /* 1111 */ PTR(98, 1), + + /* 0001 ... */ + /* 0000 */ PTR(100, 1), /* 32 */ + /* 0001 */ V(1, 5, 4), + /* 0010 */ V(6, 2, 3), + /* 0011 */ V(6, 2, 3), + /* 0100 */ V(2, 6, 4), + /* 0101 */ V(0, 6, 4), + /* 0110 */ V(1, 6, 3), + /* 0111 */ V(1, 6, 3), + /* 1000 */ V(6, 1, 3), + /* 1001 */ V(6, 1, 3), + /* 1010 */ V(5, 1, 4), + /* 1011 */ V(3, 4, 4), + /* 1100 */ V(5, 0, 4), + /* 1101 */ PTR(102, 1), + /* 1110 */ V(2, 4, 4), + /* 1111 */ V(4, 2, 4), + + /* 0010 ... */ + /* 0000 */ V(1, 4, 4), /* 48 */ + /* 0001 */ V(4, 1, 4), + /* 0010 */ V(0, 4, 4), + /* 0011 */ V(4, 0, 4), + /* 0100 */ V(2, 3, 3), + /* 0101 */ V(2, 3, 3), + /* 0110 */ V(3, 2, 3), + /* 0111 */ V(3, 2, 3), + /* 1000 */ V(1, 3, 2), + /* 1001 */ V(1, 3, 2), + /* 1010 */ V(1, 3, 2), + /* 1011 */ V(1, 3, 2), + /* 1100 */ V(3, 1, 2), + /* 1101 */ V(3, 1, 2), + /* 1110 */ V(3, 1, 2), + /* 1111 */ V(3, 1, 2), + + /* 0011 ... */ + /* 000 */ V(0, 3, 3), /* 64 */ + /* 001 */ V(3, 0, 3), + /* 010 */ V(2, 2, 2), + /* 011 */ V(2, 2, 2), + /* 100 */ V(2, 1, 1), + /* 101 */ V(2, 1, 1), + /* 110 */ V(2, 1, 1), + /* 111 */ V(2, 1, 1), + + /* 0101 ... */ + /* 0 */ V(0, 2, 1), /* 72 */ + /* 1 */ V(2, 0, 1), + + /* 0000 0000 ... */ + /* 00 */ V(7, 7, 2), /* 74 */ + /* 01 */ V(6, 7, 2), + /* 10 */ V(7, 6, 2), + /* 11 */ V(7, 5, 2), + + /* 0000 0001 ... */ + /* 000 */ V(6, 6, 2), /* 78 */ + /* 001 */ V(6, 6, 2), + /* 010 */ V(4, 7, 2), + /* 011 */ V(4, 7, 2), + /* 100 */ V(7, 4, 2), + /* 101 */ V(7, 4, 2), + /* 110 */ V(5, 7, 3), + /* 111 */ V(5, 5, 3), + + /* 0000 0010 ... */ + /* 00 */ V(5, 6, 2), /* 86 */ + /* 01 */ V(6, 5, 2), + /* 10 */ V(3, 7, 1), + /* 11 */ V(3, 7, 1), + + /* 0000 0011 ... */ + /* 0 */ V(7, 3, 1), /* 90 */ + /* 1 */ V(4, 6, 1), + + /* 0000 0100 ... */ + /* 00 */ V(4, 5, 2), /* 92 */ + /* 01 */ V(5, 4, 2), + /* 10 */ V(3, 5, 2), + /* 11 */ V(5, 3, 2), + + /* 0000 0111 ... */ + /* 0 */ V(6, 4, 1), /* 96 */ + /* 1 */ V(0, 7, 1), + + /* 0000 1111 ... */ + /* 0 */ V(4, 4, 1), /* 98 */ + /* 1 */ V(2, 5, 1), + + /* 0001 0000 ... */ + /* 0 */ V(5, 2, 1), /* 100 */ + /* 1 */ V(0, 5, 1), + + /* 0001 1101 ... */ + /* 0 */ V(4, 3, 1), /* 102 */ + /* 1 */ V(3, 3, 1) +}; + +static +union huffpair const hufftab12[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 2), + /* 0100 */ PTR(68, 3), + /* 0101 */ PTR(76, 1), + /* 0110 */ V(1, 2, 4), + /* 0111 */ V(2, 1, 4), + /* 1000 */ PTR(78, 1), + /* 1001 */ V(0, 0, 4), + /* 1010 */ V(1, 1, 3), + /* 1011 */ V(1, 1, 3), + /* 1100 */ V(0, 1, 3), + /* 1101 */ V(0, 1, 3), + /* 1110 */ V(1, 0, 3), + /* 1111 */ V(1, 0, 3), + + /* 0000 ... */ + /* 0000 */ PTR(80, 2), /* 16 */ + /* 0001 */ PTR(84, 1), + /* 0010 */ PTR(86, 1), + /* 0011 */ PTR(88, 1), + /* 0100 */ V(5, 6, 4), + /* 0101 */ V(3, 7, 4), + /* 0110 */ PTR(90, 1), + /* 0111 */ V(2, 7, 4), + /* 1000 */ V(7, 2, 4), + /* 1001 */ V(4, 6, 4), + /* 1010 */ V(6, 4, 4), + /* 1011 */ V(1, 7, 4), + /* 1100 */ V(7, 1, 4), + /* 1101 */ PTR(92, 1), + /* 1110 */ V(3, 6, 4), + /* 1111 */ V(6, 3, 4), + + /* 0001 ... */ + /* 0000 */ V(4, 5, 4), /* 32 */ + /* 0001 */ V(5, 4, 4), + /* 0010 */ V(4, 4, 4), + /* 0011 */ PTR(94, 1), + /* 0100 */ V(2, 6, 3), + /* 0101 */ V(2, 6, 3), + /* 0110 */ V(6, 2, 3), + /* 0111 */ V(6, 2, 3), + /* 1000 */ V(6, 1, 3), + /* 1001 */ V(6, 1, 3), + /* 1010 */ V(1, 6, 4), + /* 1011 */ V(6, 0, 4), + /* 1100 */ V(3, 5, 4), + /* 1101 */ V(5, 3, 4), + /* 1110 */ V(2, 5, 4), + /* 1111 */ V(5, 2, 4), + + /* 0010 ... */ + /* 0000 */ V(1, 5, 3), /* 48 */ + /* 0001 */ V(1, 5, 3), + /* 0010 */ V(5, 1, 3), + /* 0011 */ V(5, 1, 3), + /* 0100 */ V(3, 4, 3), + /* 0101 */ V(3, 4, 3), + /* 0110 */ V(4, 3, 3), + /* 0111 */ V(4, 3, 3), + /* 1000 */ V(5, 0, 4), + /* 1001 */ V(0, 4, 4), + /* 1010 */ V(2, 4, 3), + /* 1011 */ V(2, 4, 3), + /* 1100 */ V(4, 2, 3), + /* 1101 */ V(4, 2, 3), + /* 1110 */ V(1, 4, 3), + /* 1111 */ V(1, 4, 3), + + /* 0011 ... */ + /* 00 */ V(3, 3, 2), /* 64 */ + /* 01 */ V(4, 1, 2), + /* 10 */ V(2, 3, 2), + /* 11 */ V(3, 2, 2), + + /* 0100 ... */ + /* 000 */ V(4, 0, 3), /* 68 */ + /* 001 */ V(0, 3, 3), + /* 010 */ V(3, 0, 2), + /* 011 */ V(3, 0, 2), + /* 100 */ V(1, 3, 1), + /* 101 */ V(1, 3, 1), + /* 110 */ V(1, 3, 1), + /* 111 */ V(1, 3, 1), + + /* 0101 ... */ + /* 0 */ V(3, 1, 1), /* 76 */ + /* 1 */ V(2, 2, 1), + + /* 1000 ... */ + /* 0 */ V(0, 2, 1), /* 78 */ + /* 1 */ V(2, 0, 1), + + /* 0000 0000 ... */ + /* 00 */ V(7, 7, 2), /* 80 */ + /* 01 */ V(6, 7, 2), + /* 10 */ V(7, 6, 1), + /* 11 */ V(7, 6, 1), + + /* 0000 0001 ... */ + /* 0 */ V(5, 7, 1), /* 84 */ + /* 1 */ V(7, 5, 1), + + /* 0000 0010 ... */ + /* 0 */ V(6, 6, 1), /* 86 */ + /* 1 */ V(4, 7, 1), + + /* 0000 0011 ... */ + /* 0 */ V(7, 4, 1), /* 88 */ + /* 1 */ V(6, 5, 1), + + /* 0000 0110 ... */ + /* 0 */ V(7, 3, 1), /* 90 */ + /* 1 */ V(5, 5, 1), + + /* 0000 1101 ... */ + /* 0 */ V(0, 7, 1), /* 92 */ + /* 1 */ V(7, 0, 1), + + /* 0001 0011 ... */ + /* 0 */ V(0, 6, 1), /* 94 */ + /* 1 */ V(0, 5, 1) +}; + +static +union huffpair const hufftab13[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 2), + /* 0100 */ V(1, 1, 4), + /* 0101 */ V(0, 1, 4), + /* 0110 */ V(1, 0, 3), + /* 0111 */ V(1, 0, 3), + /* 1000 */ V(0, 0, 1), + /* 1001 */ V(0, 0, 1), + /* 1010 */ V(0, 0, 1), + /* 1011 */ V(0, 0, 1), + /* 1100 */ V(0, 0, 1), + /* 1101 */ V(0, 0, 1), + /* 1110 */ V(0, 0, 1), + /* 1111 */ V(0, 0, 1), + + /* 0000 ... */ + /* 0000 */ PTR(68, 4), /* 16 */ + /* 0001 */ PTR(84, 4), + /* 0010 */ PTR(100, 4), + /* 0011 */ PTR(116, 4), + /* 0100 */ PTR(132, 4), + /* 0101 */ PTR(148, 4), + /* 0110 */ PTR(164, 3), + /* 0111 */ PTR(172, 3), + /* 1000 */ PTR(180, 3), + /* 1001 */ PTR(188, 3), + /* 1010 */ PTR(196, 3), + /* 1011 */ PTR(204, 3), + /* 1100 */ PTR(212, 1), + /* 1101 */ PTR(214, 2), + /* 1110 */ PTR(218, 3), + /* 1111 */ PTR(226, 1), + + /* 0001 ... */ + /* 0000 */ PTR(228, 2), /* 32 */ + /* 0001 */ PTR(232, 2), + /* 0010 */ PTR(236, 2), + /* 0011 */ PTR(240, 2), + /* 0100 */ V(8, 1, 4), + /* 0101 */ PTR(244, 1), + /* 0110 */ PTR(246, 1), + /* 0111 */ PTR(248, 1), + /* 1000 */ PTR(250, 2), + /* 1001 */ PTR(254, 1), + /* 1010 */ V(1, 5, 4), + /* 1011 */ V(5, 1, 4), + /* 1100 */ PTR(256, 1), + /* 1101 */ PTR(258, 1), + /* 1110 */ PTR(260, 1), + /* 1111 */ V(1, 4, 4), + + /* 0010 ... */ + /* 0000 */ V(4, 1, 3), /* 48 */ + /* 0001 */ V(4, 1, 3), + /* 0010 */ V(0, 4, 4), + /* 0011 */ V(4, 0, 4), + /* 0100 */ V(2, 3, 4), + /* 0101 */ V(3, 2, 4), + /* 0110 */ V(1, 3, 3), + /* 0111 */ V(1, 3, 3), + /* 1000 */ V(3, 1, 3), + /* 1001 */ V(3, 1, 3), + /* 1010 */ V(0, 3, 3), + /* 1011 */ V(0, 3, 3), + /* 1100 */ V(3, 0, 3), + /* 1101 */ V(3, 0, 3), + /* 1110 */ V(2, 2, 3), + /* 1111 */ V(2, 2, 3), + + /* 0011 ... */ + /* 00 */ V(1, 2, 2), /* 64 */ + /* 01 */ V(2, 1, 2), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 0000 */ PTR(262, 4), /* 68 */ + /* 0001 */ PTR(278, 4), + /* 0010 */ PTR(294, 4), + /* 0011 */ PTR(310, 3), + /* 0100 */ PTR(318, 2), + /* 0101 */ PTR(322, 2), + /* 0110 */ PTR(326, 3), + /* 0111 */ PTR(334, 2), + /* 1000 */ PTR(338, 1), + /* 1001 */ PTR(340, 2), + /* 1010 */ PTR(344, 2), + /* 1011 */ PTR(348, 2), + /* 1100 */ PTR(352, 2), + /* 1101 */ PTR(356, 2), + /* 1110 */ V(1, 15, 4), + /* 1111 */ V(15, 1, 4), + + /* 0000 0001 ... */ + /* 0000 */ V(15, 0, 4), /* 84 */ + /* 0001 */ PTR(360, 1), + /* 0010 */ PTR(362, 1), + /* 0011 */ PTR(364, 1), + /* 0100 */ V(14, 2, 4), + /* 0101 */ PTR(366, 1), + /* 0110 */ V(1, 14, 4), + /* 0111 */ V(14, 1, 4), + /* 1000 */ PTR(368, 1), + /* 1001 */ PTR(370, 1), + /* 1010 */ PTR(372, 1), + /* 1011 */ PTR(374, 1), + /* 1100 */ PTR(376, 1), + /* 1101 */ PTR(378, 1), + /* 1110 */ V(12, 6, 4), + /* 1111 */ V(3, 13, 4), + + /* 0000 0010 ... */ + /* 0000 */ PTR(380, 1), /* 100 */ + /* 0001 */ V(2, 13, 4), + /* 0010 */ V(13, 2, 4), + /* 0011 */ V(1, 13, 4), + /* 0100 */ V(11, 7, 4), + /* 0101 */ PTR(382, 1), + /* 0110 */ PTR(384, 1), + /* 0111 */ V(12, 3, 4), + /* 1000 */ PTR(386, 1), + /* 1001 */ V(4, 11, 4), + /* 1010 */ V(13, 1, 3), + /* 1011 */ V(13, 1, 3), + /* 1100 */ V(0, 13, 4), + /* 1101 */ V(13, 0, 4), + /* 1110 */ V(8, 10, 4), + /* 1111 */ V(10, 8, 4), + + /* 0000 0011 ... */ + /* 0000 */ V(4, 12, 4), /* 116 */ + /* 0001 */ V(12, 4, 4), + /* 0010 */ V(6, 11, 4), + /* 0011 */ V(11, 6, 4), + /* 0100 */ V(3, 12, 3), + /* 0101 */ V(3, 12, 3), + /* 0110 */ V(2, 12, 3), + /* 0111 */ V(2, 12, 3), + /* 1000 */ V(12, 2, 3), + /* 1001 */ V(12, 2, 3), + /* 1010 */ V(5, 11, 3), + /* 1011 */ V(5, 11, 3), + /* 1100 */ V(11, 5, 4), + /* 1101 */ V(8, 9, 4), + /* 1110 */ V(1, 12, 3), + /* 1111 */ V(1, 12, 3), + + /* 0000 0100 ... */ + /* 0000 */ V(12, 1, 3), /* 132 */ + /* 0001 */ V(12, 1, 3), + /* 0010 */ V(9, 8, 4), + /* 0011 */ V(0, 12, 4), + /* 0100 */ V(12, 0, 3), + /* 0101 */ V(12, 0, 3), + /* 0110 */ V(11, 4, 4), + /* 0111 */ V(6, 10, 4), + /* 1000 */ V(10, 6, 4), + /* 1001 */ V(7, 9, 4), + /* 1010 */ V(3, 11, 3), + /* 1011 */ V(3, 11, 3), + /* 1100 */ V(11, 3, 3), + /* 1101 */ V(11, 3, 3), + /* 1110 */ V(8, 8, 4), + /* 1111 */ V(5, 10, 4), + + /* 0000 0101 ... */ + /* 0000 */ V(2, 11, 3), /* 148 */ + /* 0001 */ V(2, 11, 3), + /* 0010 */ V(10, 5, 4), + /* 0011 */ V(6, 9, 4), + /* 0100 */ V(10, 4, 3), + /* 0101 */ V(10, 4, 3), + /* 0110 */ V(7, 8, 4), + /* 0111 */ V(8, 7, 4), + /* 1000 */ V(9, 4, 3), + /* 1001 */ V(9, 4, 3), + /* 1010 */ V(7, 7, 4), + /* 1011 */ V(7, 6, 4), + /* 1100 */ V(11, 2, 2), + /* 1101 */ V(11, 2, 2), + /* 1110 */ V(11, 2, 2), + /* 1111 */ V(11, 2, 2), + + /* 0000 0110 ... */ + /* 000 */ V(1, 11, 2), /* 164 */ + /* 001 */ V(1, 11, 2), + /* 010 */ V(11, 1, 2), + /* 011 */ V(11, 1, 2), + /* 100 */ V(0, 11, 3), + /* 101 */ V(11, 0, 3), + /* 110 */ V(9, 6, 3), + /* 111 */ V(4, 10, 3), + + /* 0000 0111 ... */ + /* 000 */ V(3, 10, 3), /* 172 */ + /* 001 */ V(10, 3, 3), + /* 010 */ V(5, 9, 3), + /* 011 */ V(9, 5, 3), + /* 100 */ V(2, 10, 2), + /* 101 */ V(2, 10, 2), + /* 110 */ V(10, 2, 2), + /* 111 */ V(10, 2, 2), + + /* 0000 1000 ... */ + /* 000 */ V(1, 10, 2), /* 180 */ + /* 001 */ V(1, 10, 2), + /* 010 */ V(10, 1, 2), + /* 011 */ V(10, 1, 2), + /* 100 */ V(0, 10, 3), + /* 101 */ V(6, 8, 3), + /* 110 */ V(10, 0, 2), + /* 111 */ V(10, 0, 2), + + /* 0000 1001 ... */ + /* 000 */ V(8, 6, 3), /* 188 */ + /* 001 */ V(4, 9, 3), + /* 010 */ V(9, 3, 2), + /* 011 */ V(9, 3, 2), + /* 100 */ V(3, 9, 3), + /* 101 */ V(5, 8, 3), + /* 110 */ V(8, 5, 3), + /* 111 */ V(6, 7, 3), + + /* 0000 1010 ... */ + /* 000 */ V(2, 9, 2), /* 196 */ + /* 001 */ V(2, 9, 2), + /* 010 */ V(9, 2, 2), + /* 011 */ V(9, 2, 2), + /* 100 */ V(5, 7, 3), + /* 101 */ V(7, 5, 3), + /* 110 */ V(3, 8, 2), + /* 111 */ V(3, 8, 2), + + /* 0000 1011 ... */ + /* 000 */ V(8, 3, 2), /* 204 */ + /* 001 */ V(8, 3, 2), + /* 010 */ V(6, 6, 3), + /* 011 */ V(4, 7, 3), + /* 100 */ V(7, 4, 3), + /* 101 */ V(5, 6, 3), + /* 110 */ V(6, 5, 3), + /* 111 */ V(7, 3, 3), + + /* 0000 1100 ... */ + /* 0 */ V(1, 9, 1), /* 212 */ + /* 1 */ V(9, 1, 1), + + /* 0000 1101 ... */ + /* 00 */ V(0, 9, 2), /* 214 */ + /* 01 */ V(9, 0, 2), + /* 10 */ V(4, 8, 2), + /* 11 */ V(8, 4, 2), + + /* 0000 1110 ... */ + /* 000 */ V(7, 2, 2), /* 218 */ + /* 001 */ V(7, 2, 2), + /* 010 */ V(4, 6, 3), + /* 011 */ V(6, 4, 3), + /* 100 */ V(2, 8, 1), + /* 101 */ V(2, 8, 1), + /* 110 */ V(2, 8, 1), + /* 111 */ V(2, 8, 1), + + /* 0000 1111 ... */ + /* 0 */ V(8, 2, 1), /* 226 */ + /* 1 */ V(1, 8, 1), + + /* 0001 0000 ... */ + /* 00 */ V(3, 7, 2), /* 228 */ + /* 01 */ V(2, 7, 2), + /* 10 */ V(1, 7, 1), + /* 11 */ V(1, 7, 1), + + /* 0001 0001 ... */ + /* 00 */ V(7, 1, 1), /* 232 */ + /* 01 */ V(7, 1, 1), + /* 10 */ V(5, 5, 2), + /* 11 */ V(0, 7, 2), + + /* 0001 0010 ... */ + /* 00 */ V(7, 0, 2), /* 236 */ + /* 01 */ V(3, 6, 2), + /* 10 */ V(6, 3, 2), + /* 11 */ V(4, 5, 2), + + /* 0001 0011 ... */ + /* 00 */ V(5, 4, 2), /* 240 */ + /* 01 */ V(2, 6, 2), + /* 10 */ V(6, 2, 2), + /* 11 */ V(3, 5, 2), + + /* 0001 0101 ... */ + /* 0 */ V(0, 8, 1), /* 244 */ + /* 1 */ V(8, 0, 1), + + /* 0001 0110 ... */ + /* 0 */ V(1, 6, 1), /* 246 */ + /* 1 */ V(6, 1, 1), + + /* 0001 0111 ... */ + /* 0 */ V(0, 6, 1), /* 248 */ + /* 1 */ V(6, 0, 1), + + /* 0001 1000 ... */ + /* 00 */ V(5, 3, 2), /* 250 */ + /* 01 */ V(4, 4, 2), + /* 10 */ V(2, 5, 1), + /* 11 */ V(2, 5, 1), + + /* 0001 1001 ... */ + /* 0 */ V(5, 2, 1), /* 254 */ + /* 1 */ V(0, 5, 1), + + /* 0001 1100 ... */ + /* 0 */ V(3, 4, 1), /* 256 */ + /* 1 */ V(4, 3, 1), + + /* 0001 1101 ... */ + /* 0 */ V(5, 0, 1), /* 258 */ + /* 1 */ V(2, 4, 1), + + /* 0001 1110 ... */ + /* 0 */ V(4, 2, 1), /* 260 */ + /* 1 */ V(3, 3, 1), + + /* 0000 0000 0000 ... */ + /* 0000 */ PTR(388, 3), /* 262 */ + /* 0001 */ V(15, 15, 4), + /* 0010 */ V(14, 15, 4), + /* 0011 */ V(13, 15, 4), + /* 0100 */ V(14, 14, 4), + /* 0101 */ V(12, 15, 4), + /* 0110 */ V(13, 14, 4), + /* 0111 */ V(11, 15, 4), + /* 1000 */ V(15, 11, 4), + /* 1001 */ V(12, 14, 4), + /* 1010 */ V(13, 12, 4), + /* 1011 */ PTR(396, 1), + /* 1100 */ V(14, 12, 3), + /* 1101 */ V(14, 12, 3), + /* 1110 */ V(13, 13, 3), + /* 1111 */ V(13, 13, 3), + + /* 0000 0000 0001 ... */ + /* 0000 */ V(15, 10, 4), /* 278 */ + /* 0001 */ V(12, 13, 4), + /* 0010 */ V(11, 14, 3), + /* 0011 */ V(11, 14, 3), + /* 0100 */ V(14, 11, 3), + /* 0101 */ V(14, 11, 3), + /* 0110 */ V(9, 15, 3), + /* 0111 */ V(9, 15, 3), + /* 1000 */ V(15, 9, 3), + /* 1001 */ V(15, 9, 3), + /* 1010 */ V(14, 10, 3), + /* 1011 */ V(14, 10, 3), + /* 1100 */ V(11, 13, 3), + /* 1101 */ V(11, 13, 3), + /* 1110 */ V(13, 11, 3), + /* 1111 */ V(13, 11, 3), + + /* 0000 0000 0010 ... */ + /* 0000 */ V(8, 15, 3), /* 294 */ + /* 0001 */ V(8, 15, 3), + /* 0010 */ V(15, 8, 3), + /* 0011 */ V(15, 8, 3), + /* 0100 */ V(12, 12, 3), + /* 0101 */ V(12, 12, 3), + /* 0110 */ V(10, 14, 4), + /* 0111 */ V(9, 14, 4), + /* 1000 */ V(8, 14, 3), + /* 1001 */ V(8, 14, 3), + /* 1010 */ V(7, 15, 4), + /* 1011 */ V(7, 14, 4), + /* 1100 */ V(15, 7, 2), + /* 1101 */ V(15, 7, 2), + /* 1110 */ V(15, 7, 2), + /* 1111 */ V(15, 7, 2), + + /* 0000 0000 0011 ... */ + /* 000 */ V(13, 10, 2), /* 310 */ + /* 001 */ V(13, 10, 2), + /* 010 */ V(10, 13, 3), + /* 011 */ V(11, 12, 3), + /* 100 */ V(12, 11, 3), + /* 101 */ V(15, 6, 3), + /* 110 */ V(6, 15, 2), + /* 111 */ V(6, 15, 2), + + /* 0000 0000 0100 ... */ + /* 00 */ V(14, 8, 2), /* 318 */ + /* 01 */ V(5, 15, 2), + /* 10 */ V(9, 13, 2), + /* 11 */ V(13, 9, 2), + + /* 0000 0000 0101 ... */ + /* 00 */ V(15, 5, 2), /* 322 */ + /* 01 */ V(14, 7, 2), + /* 10 */ V(10, 12, 2), + /* 11 */ V(11, 11, 2), + + /* 0000 0000 0110 ... */ + /* 000 */ V(4, 15, 2), /* 326 */ + /* 001 */ V(4, 15, 2), + /* 010 */ V(15, 4, 2), + /* 011 */ V(15, 4, 2), + /* 100 */ V(12, 10, 3), + /* 101 */ V(14, 6, 3), + /* 110 */ V(15, 3, 2), + /* 111 */ V(15, 3, 2), + + /* 0000 0000 0111 ... */ + /* 00 */ V(3, 15, 1), /* 334 */ + /* 01 */ V(3, 15, 1), + /* 10 */ V(8, 13, 2), + /* 11 */ V(13, 8, 2), + + /* 0000 0000 1000 ... */ + /* 0 */ V(2, 15, 1), /* 338 */ + /* 1 */ V(15, 2, 1), + + /* 0000 0000 1001 ... */ + /* 00 */ V(6, 14, 2), /* 340 */ + /* 01 */ V(9, 12, 2), + /* 10 */ V(0, 15, 1), + /* 11 */ V(0, 15, 1), + + /* 0000 0000 1010 ... */ + /* 00 */ V(12, 9, 2), /* 344 */ + /* 01 */ V(5, 14, 2), + /* 10 */ V(10, 11, 1), + /* 11 */ V(10, 11, 1), + + /* 0000 0000 1011 ... */ + /* 00 */ V(7, 13, 2), /* 348 */ + /* 01 */ V(13, 7, 2), + /* 10 */ V(4, 14, 1), + /* 11 */ V(4, 14, 1), + + /* 0000 0000 1100 ... */ + /* 00 */ V(12, 8, 2), /* 352 */ + /* 01 */ V(13, 6, 2), + /* 10 */ V(3, 14, 1), + /* 11 */ V(3, 14, 1), + + /* 0000 0000 1101 ... */ + /* 00 */ V(11, 9, 1), /* 356 */ + /* 01 */ V(11, 9, 1), + /* 10 */ V(9, 11, 2), + /* 11 */ V(10, 10, 2), + + /* 0000 0001 0001 ... */ + /* 0 */ V(11, 10, 1), /* 360 */ + /* 1 */ V(14, 5, 1), + + /* 0000 0001 0010 ... */ + /* 0 */ V(14, 4, 1), /* 362 */ + /* 1 */ V(8, 12, 1), + + /* 0000 0001 0011 ... */ + /* 0 */ V(6, 13, 1), /* 364 */ + /* 1 */ V(14, 3, 1), + + /* 0000 0001 0101 ... */ + /* 0 */ V(2, 14, 1), /* 366 */ + /* 1 */ V(0, 14, 1), + + /* 0000 0001 1000 ... */ + /* 0 */ V(14, 0, 1), /* 368 */ + /* 1 */ V(5, 13, 1), + + /* 0000 0001 1001 ... */ + /* 0 */ V(13, 5, 1), /* 370 */ + /* 1 */ V(7, 12, 1), + + /* 0000 0001 1010 ... */ + /* 0 */ V(12, 7, 1), /* 372 */ + /* 1 */ V(4, 13, 1), + + /* 0000 0001 1011 ... */ + /* 0 */ V(8, 11, 1), /* 374 */ + /* 1 */ V(11, 8, 1), + + /* 0000 0001 1100 ... */ + /* 0 */ V(13, 4, 1), /* 376 */ + /* 1 */ V(9, 10, 1), + + /* 0000 0001 1101 ... */ + /* 0 */ V(10, 9, 1), /* 378 */ + /* 1 */ V(6, 12, 1), + + /* 0000 0010 0000 ... */ + /* 0 */ V(13, 3, 1), /* 380 */ + /* 1 */ V(7, 11, 1), + + /* 0000 0010 0101 ... */ + /* 0 */ V(5, 12, 1), /* 382 */ + /* 1 */ V(12, 5, 1), + + /* 0000 0010 0110 ... */ + /* 0 */ V(9, 9, 1), /* 384 */ + /* 1 */ V(7, 10, 1), + + /* 0000 0010 1000 ... */ + /* 0 */ V(10, 7, 1), /* 386 */ + /* 1 */ V(9, 7, 1), + + /* 0000 0000 0000 0000 ... */ + /* 000 */ V(15, 14, 3), /* 388 */ + /* 001 */ V(15, 12, 3), + /* 010 */ V(15, 13, 2), + /* 011 */ V(15, 13, 2), + /* 100 */ V(14, 13, 1), + /* 101 */ V(14, 13, 1), + /* 110 */ V(14, 13, 1), + /* 111 */ V(14, 13, 1), + + /* 0000 0000 0000 1011 ... */ + /* 0 */ V(10, 15, 1), /* 396 */ + /* 1 */ V(14, 9, 1) +}; + +static +union huffpair const hufftab15[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 4), + /* 0100 */ PTR(80, 4), + /* 0101 */ PTR(96, 3), + /* 0110 */ PTR(104, 3), + /* 0111 */ PTR(112, 2), + /* 1000 */ PTR(116, 1), + /* 1001 */ PTR(118, 1), + /* 1010 */ V(1, 1, 3), + /* 1011 */ V(1, 1, 3), + /* 1100 */ V(0, 1, 4), + /* 1101 */ V(1, 0, 4), + /* 1110 */ V(0, 0, 3), + /* 1111 */ V(0, 0, 3), + + /* 0000 ... */ + /* 0000 */ PTR(120, 4), /* 16 */ + /* 0001 */ PTR(136, 4), + /* 0010 */ PTR(152, 4), + /* 0011 */ PTR(168, 4), + /* 0100 */ PTR(184, 4), + /* 0101 */ PTR(200, 3), + /* 0110 */ PTR(208, 3), + /* 0111 */ PTR(216, 4), + /* 1000 */ PTR(232, 3), + /* 1001 */ PTR(240, 3), + /* 1010 */ PTR(248, 3), + /* 1011 */ PTR(256, 3), + /* 1100 */ PTR(264, 2), + /* 1101 */ PTR(268, 3), + /* 1110 */ PTR(276, 3), + /* 1111 */ PTR(284, 2), + + /* 0001 ... */ + /* 0000 */ PTR(288, 2), /* 32 */ + /* 0001 */ PTR(292, 2), + /* 0010 */ PTR(296, 2), + /* 0011 */ PTR(300, 2), + /* 0100 */ PTR(304, 2), + /* 0101 */ PTR(308, 2), + /* 0110 */ PTR(312, 2), + /* 0111 */ PTR(316, 2), + /* 1000 */ PTR(320, 1), + /* 1001 */ PTR(322, 1), + /* 1010 */ PTR(324, 1), + /* 1011 */ PTR(326, 2), + /* 1100 */ PTR(330, 1), + /* 1101 */ PTR(332, 1), + /* 1110 */ PTR(334, 2), + /* 1111 */ PTR(338, 1), + + /* 0010 ... */ + /* 0000 */ PTR(340, 1), /* 48 */ + /* 0001 */ PTR(342, 1), + /* 0010 */ V(9, 1, 4), + /* 0011 */ PTR(344, 1), + /* 0100 */ PTR(346, 1), + /* 0101 */ PTR(348, 1), + /* 0110 */ PTR(350, 1), + /* 0111 */ PTR(352, 1), + /* 1000 */ V(2, 8, 4), + /* 1001 */ V(8, 2, 4), + /* 1010 */ V(1, 8, 4), + /* 1011 */ V(8, 1, 4), + /* 1100 */ PTR(354, 1), + /* 1101 */ PTR(356, 1), + /* 1110 */ PTR(358, 1), + /* 1111 */ PTR(360, 1), + + /* 0011 ... */ + /* 0000 */ V(2, 7, 4), /* 64 */ + /* 0001 */ V(7, 2, 4), + /* 0010 */ V(6, 4, 4), + /* 0011 */ V(1, 7, 4), + /* 0100 */ V(5, 5, 4), + /* 0101 */ V(7, 1, 4), + /* 0110 */ PTR(362, 1), + /* 0111 */ V(3, 6, 4), + /* 1000 */ V(6, 3, 4), + /* 1001 */ V(4, 5, 4), + /* 1010 */ V(5, 4, 4), + /* 1011 */ V(2, 6, 4), + /* 1100 */ V(6, 2, 4), + /* 1101 */ V(1, 6, 4), + /* 1110 */ PTR(364, 1), + /* 1111 */ V(3, 5, 4), + + /* 0100 ... */ + /* 0000 */ V(6, 1, 3), /* 80 */ + /* 0001 */ V(6, 1, 3), + /* 0010 */ V(5, 3, 4), + /* 0011 */ V(4, 4, 4), + /* 0100 */ V(2, 5, 3), + /* 0101 */ V(2, 5, 3), + /* 0110 */ V(5, 2, 3), + /* 0111 */ V(5, 2, 3), + /* 1000 */ V(1, 5, 3), + /* 1001 */ V(1, 5, 3), + /* 1010 */ V(5, 1, 3), + /* 1011 */ V(5, 1, 3), + /* 1100 */ V(0, 5, 4), + /* 1101 */ V(5, 0, 4), + /* 1110 */ V(3, 4, 3), + /* 1111 */ V(3, 4, 3), + + /* 0101 ... */ + /* 000 */ V(4, 3, 3), /* 96 */ + /* 001 */ V(2, 4, 3), + /* 010 */ V(4, 2, 3), + /* 011 */ V(3, 3, 3), + /* 100 */ V(4, 1, 2), + /* 101 */ V(4, 1, 2), + /* 110 */ V(1, 4, 3), + /* 111 */ V(0, 4, 3), + + /* 0110 ... */ + /* 000 */ V(2, 3, 2), /* 104 */ + /* 001 */ V(2, 3, 2), + /* 010 */ V(3, 2, 2), + /* 011 */ V(3, 2, 2), + /* 100 */ V(4, 0, 3), + /* 101 */ V(0, 3, 3), + /* 110 */ V(1, 3, 2), + /* 111 */ V(1, 3, 2), + + /* 0111 ... */ + /* 00 */ V(3, 1, 2), /* 112 */ + /* 01 */ V(3, 0, 2), + /* 10 */ V(2, 2, 1), + /* 11 */ V(2, 2, 1), + + /* 1000 ... */ + /* 0 */ V(1, 2, 1), /* 116 */ + /* 1 */ V(2, 1, 1), + + /* 1001 ... */ + /* 0 */ V(0, 2, 1), /* 118 */ + /* 1 */ V(2, 0, 1), + + /* 0000 0000 ... */ + /* 0000 */ PTR(366, 1), /* 120 */ + /* 0001 */ PTR(368, 1), + /* 0010 */ V(14, 14, 4), + /* 0011 */ PTR(370, 1), + /* 0100 */ PTR(372, 1), + /* 0101 */ PTR(374, 1), + /* 0110 */ V(15, 11, 4), + /* 0111 */ PTR(376, 1), + /* 1000 */ V(13, 13, 4), + /* 1001 */ V(10, 15, 4), + /* 1010 */ V(15, 10, 4), + /* 1011 */ V(11, 14, 4), + /* 1100 */ V(14, 11, 4), + /* 1101 */ V(12, 13, 4), + /* 1110 */ V(13, 12, 4), + /* 1111 */ V(9, 15, 4), + + /* 0000 0001 ... */ + /* 0000 */ V(15, 9, 4), /* 136 */ + /* 0001 */ V(14, 10, 4), + /* 0010 */ V(11, 13, 4), + /* 0011 */ V(13, 11, 4), + /* 0100 */ V(8, 15, 4), + /* 0101 */ V(15, 8, 4), + /* 0110 */ V(12, 12, 4), + /* 0111 */ V(9, 14, 4), + /* 1000 */ V(14, 9, 4), + /* 1001 */ V(7, 15, 4), + /* 1010 */ V(15, 7, 4), + /* 1011 */ V(10, 13, 4), + /* 1100 */ V(13, 10, 4), + /* 1101 */ V(11, 12, 4), + /* 1110 */ V(6, 15, 4), + /* 1111 */ PTR(378, 1), + + /* 0000 0010 ... */ + /* 0000 */ V(12, 11, 3), /* 152 */ + /* 0001 */ V(12, 11, 3), + /* 0010 */ V(15, 6, 3), + /* 0011 */ V(15, 6, 3), + /* 0100 */ V(8, 14, 4), + /* 0101 */ V(14, 8, 4), + /* 0110 */ V(5, 15, 4), + /* 0111 */ V(9, 13, 4), + /* 1000 */ V(15, 5, 3), + /* 1001 */ V(15, 5, 3), + /* 1010 */ V(7, 14, 3), + /* 1011 */ V(7, 14, 3), + /* 1100 */ V(14, 7, 3), + /* 1101 */ V(14, 7, 3), + /* 1110 */ V(10, 12, 3), + /* 1111 */ V(10, 12, 3), + + /* 0000 0011 ... */ + /* 0000 */ V(12, 10, 3), /* 168 */ + /* 0001 */ V(12, 10, 3), + /* 0010 */ V(11, 11, 3), + /* 0011 */ V(11, 11, 3), + /* 0100 */ V(13, 9, 4), + /* 0101 */ V(8, 13, 4), + /* 0110 */ V(4, 15, 3), + /* 0111 */ V(4, 15, 3), + /* 1000 */ V(15, 4, 3), + /* 1001 */ V(15, 4, 3), + /* 1010 */ V(3, 15, 3), + /* 1011 */ V(3, 15, 3), + /* 1100 */ V(15, 3, 3), + /* 1101 */ V(15, 3, 3), + /* 1110 */ V(13, 8, 3), + /* 1111 */ V(13, 8, 3), + + /* 0000 0100 ... */ + /* 0000 */ V(14, 6, 3), /* 184 */ + /* 0001 */ V(14, 6, 3), + /* 0010 */ V(2, 15, 3), + /* 0011 */ V(2, 15, 3), + /* 0100 */ V(15, 2, 3), + /* 0101 */ V(15, 2, 3), + /* 0110 */ V(6, 14, 4), + /* 0111 */ V(15, 0, 4), + /* 1000 */ V(1, 15, 3), + /* 1001 */ V(1, 15, 3), + /* 1010 */ V(15, 1, 3), + /* 1011 */ V(15, 1, 3), + /* 1100 */ V(9, 12, 3), + /* 1101 */ V(9, 12, 3), + /* 1110 */ V(12, 9, 3), + /* 1111 */ V(12, 9, 3), + + /* 0000 0101 ... */ + /* 000 */ V(5, 14, 3), /* 200 */ + /* 001 */ V(10, 11, 3), + /* 010 */ V(11, 10, 3), + /* 011 */ V(14, 5, 3), + /* 100 */ V(7, 13, 3), + /* 101 */ V(13, 7, 3), + /* 110 */ V(4, 14, 3), + /* 111 */ V(14, 4, 3), + + /* 0000 0110 ... */ + /* 000 */ V(8, 12, 3), /* 208 */ + /* 001 */ V(12, 8, 3), + /* 010 */ V(3, 14, 3), + /* 011 */ V(6, 13, 3), + /* 100 */ V(13, 6, 3), + /* 101 */ V(14, 3, 3), + /* 110 */ V(9, 11, 3), + /* 111 */ V(11, 9, 3), + + /* 0000 0111 ... */ + /* 0000 */ V(2, 14, 3), /* 216 */ + /* 0001 */ V(2, 14, 3), + /* 0010 */ V(10, 10, 3), + /* 0011 */ V(10, 10, 3), + /* 0100 */ V(14, 2, 3), + /* 0101 */ V(14, 2, 3), + /* 0110 */ V(1, 14, 3), + /* 0111 */ V(1, 14, 3), + /* 1000 */ V(14, 1, 3), + /* 1001 */ V(14, 1, 3), + /* 1010 */ V(0, 14, 4), + /* 1011 */ V(14, 0, 4), + /* 1100 */ V(5, 13, 3), + /* 1101 */ V(5, 13, 3), + /* 1110 */ V(13, 5, 3), + /* 1111 */ V(13, 5, 3), + + /* 0000 1000 ... */ + /* 000 */ V(7, 12, 3), /* 232 */ + /* 001 */ V(12, 7, 3), + /* 010 */ V(4, 13, 3), + /* 011 */ V(8, 11, 3), + /* 100 */ V(13, 4, 2), + /* 101 */ V(13, 4, 2), + /* 110 */ V(11, 8, 3), + /* 111 */ V(9, 10, 3), + + /* 0000 1001 ... */ + /* 000 */ V(10, 9, 3), /* 240 */ + /* 001 */ V(6, 12, 3), + /* 010 */ V(12, 6, 3), + /* 011 */ V(3, 13, 3), + /* 100 */ V(13, 3, 2), + /* 101 */ V(13, 3, 2), + /* 110 */ V(13, 2, 2), + /* 111 */ V(13, 2, 2), + + /* 0000 1010 ... */ + /* 000 */ V(2, 13, 3), /* 248 */ + /* 001 */ V(0, 13, 3), + /* 010 */ V(1, 13, 2), + /* 011 */ V(1, 13, 2), + /* 100 */ V(7, 11, 2), + /* 101 */ V(7, 11, 2), + /* 110 */ V(11, 7, 2), + /* 111 */ V(11, 7, 2), + + /* 0000 1011 ... */ + /* 000 */ V(13, 1, 2), /* 256 */ + /* 001 */ V(13, 1, 2), + /* 010 */ V(5, 12, 3), + /* 011 */ V(13, 0, 3), + /* 100 */ V(12, 5, 2), + /* 101 */ V(12, 5, 2), + /* 110 */ V(8, 10, 2), + /* 111 */ V(8, 10, 2), + + /* 0000 1100 ... */ + /* 00 */ V(10, 8, 2), /* 264 */ + /* 01 */ V(4, 12, 2), + /* 10 */ V(12, 4, 2), + /* 11 */ V(6, 11, 2), + + /* 0000 1101 ... */ + /* 000 */ V(11, 6, 2), /* 268 */ + /* 001 */ V(11, 6, 2), + /* 010 */ V(9, 9, 3), + /* 011 */ V(0, 12, 3), + /* 100 */ V(3, 12, 2), + /* 101 */ V(3, 12, 2), + /* 110 */ V(12, 3, 2), + /* 111 */ V(12, 3, 2), + + /* 0000 1110 ... */ + /* 000 */ V(7, 10, 2), /* 276 */ + /* 001 */ V(7, 10, 2), + /* 010 */ V(10, 7, 2), + /* 011 */ V(10, 7, 2), + /* 100 */ V(10, 6, 2), + /* 101 */ V(10, 6, 2), + /* 110 */ V(12, 0, 3), + /* 111 */ V(0, 11, 3), + + /* 0000 1111 ... */ + /* 00 */ V(12, 2, 1), /* 284 */ + /* 01 */ V(12, 2, 1), + /* 10 */ V(2, 12, 2), + /* 11 */ V(5, 11, 2), + + /* 0001 0000 ... */ + /* 00 */ V(11, 5, 2), /* 288 */ + /* 01 */ V(1, 12, 2), + /* 10 */ V(8, 9, 2), + /* 11 */ V(9, 8, 2), + + /* 0001 0001 ... */ + /* 00 */ V(12, 1, 2), /* 292 */ + /* 01 */ V(4, 11, 2), + /* 10 */ V(11, 4, 2), + /* 11 */ V(6, 10, 2), + + /* 0001 0010 ... */ + /* 00 */ V(3, 11, 2), /* 296 */ + /* 01 */ V(7, 9, 2), + /* 10 */ V(11, 3, 1), + /* 11 */ V(11, 3, 1), + + /* 0001 0011 ... */ + /* 00 */ V(9, 7, 2), /* 300 */ + /* 01 */ V(8, 8, 2), + /* 10 */ V(2, 11, 2), + /* 11 */ V(5, 10, 2), + + /* 0001 0100 ... */ + /* 00 */ V(11, 2, 1), /* 304 */ + /* 01 */ V(11, 2, 1), + /* 10 */ V(10, 5, 2), + /* 11 */ V(1, 11, 2), + + /* 0001 0101 ... */ + /* 00 */ V(11, 1, 1), /* 308 */ + /* 01 */ V(11, 1, 1), + /* 10 */ V(11, 0, 2), + /* 11 */ V(6, 9, 2), + + /* 0001 0110 ... */ + /* 00 */ V(9, 6, 2), /* 312 */ + /* 01 */ V(4, 10, 2), + /* 10 */ V(10, 4, 2), + /* 11 */ V(7, 8, 2), + + /* 0001 0111 ... */ + /* 00 */ V(8, 7, 2), /* 316 */ + /* 01 */ V(3, 10, 2), + /* 10 */ V(10, 3, 1), + /* 11 */ V(10, 3, 1), + + /* 0001 1000 ... */ + /* 0 */ V(5, 9, 1), /* 320 */ + /* 1 */ V(9, 5, 1), + + /* 0001 1001 ... */ + /* 0 */ V(2, 10, 1), /* 322 */ + /* 1 */ V(10, 2, 1), + + /* 0001 1010 ... */ + /* 0 */ V(1, 10, 1), /* 324 */ + /* 1 */ V(10, 1, 1), + + /* 0001 1011 ... */ + /* 00 */ V(0, 10, 2), /* 326 */ + /* 01 */ V(10, 0, 2), + /* 10 */ V(6, 8, 1), + /* 11 */ V(6, 8, 1), + + /* 0001 1100 ... */ + /* 0 */ V(8, 6, 1), /* 330 */ + /* 1 */ V(4, 9, 1), + + /* 0001 1101 ... */ + /* 0 */ V(9, 4, 1), /* 332 */ + /* 1 */ V(3, 9, 1), + + /* 0001 1110 ... */ + /* 00 */ V(9, 3, 1), /* 334 */ + /* 01 */ V(9, 3, 1), + /* 10 */ V(7, 7, 2), + /* 11 */ V(0, 9, 2), + + /* 0001 1111 ... */ + /* 0 */ V(5, 8, 1), /* 338 */ + /* 1 */ V(8, 5, 1), + + /* 0010 0000 ... */ + /* 0 */ V(2, 9, 1), /* 340 */ + /* 1 */ V(6, 7, 1), + + /* 0010 0001 ... */ + /* 0 */ V(7, 6, 1), /* 342 */ + /* 1 */ V(9, 2, 1), + + /* 0010 0011 ... */ + /* 0 */ V(1, 9, 1), /* 344 */ + /* 1 */ V(9, 0, 1), + + /* 0010 0100 ... */ + /* 0 */ V(4, 8, 1), /* 346 */ + /* 1 */ V(8, 4, 1), + + /* 0010 0101 ... */ + /* 0 */ V(5, 7, 1), /* 348 */ + /* 1 */ V(7, 5, 1), + + /* 0010 0110 ... */ + /* 0 */ V(3, 8, 1), /* 350 */ + /* 1 */ V(8, 3, 1), + + /* 0010 0111 ... */ + /* 0 */ V(6, 6, 1), /* 352 */ + /* 1 */ V(4, 7, 1), + + /* 0010 1100 ... */ + /* 0 */ V(7, 4, 1), /* 354 */ + /* 1 */ V(0, 8, 1), + + /* 0010 1101 ... */ + /* 0 */ V(8, 0, 1), /* 356 */ + /* 1 */ V(5, 6, 1), + + /* 0010 1110 ... */ + /* 0 */ V(6, 5, 1), /* 358 */ + /* 1 */ V(3, 7, 1), + + /* 0010 1111 ... */ + /* 0 */ V(7, 3, 1), /* 360 */ + /* 1 */ V(4, 6, 1), + + /* 0011 0110 ... */ + /* 0 */ V(0, 7, 1), /* 362 */ + /* 1 */ V(7, 0, 1), + + /* 0011 1110 ... */ + /* 0 */ V(0, 6, 1), /* 364 */ + /* 1 */ V(6, 0, 1), + + /* 0000 0000 0000 ... */ + /* 0 */ V(15, 15, 1), /* 366 */ + /* 1 */ V(14, 15, 1), + + /* 0000 0000 0001 ... */ + /* 0 */ V(15, 14, 1), /* 368 */ + /* 1 */ V(13, 15, 1), + + /* 0000 0000 0011 ... */ + /* 0 */ V(15, 13, 1), /* 370 */ + /* 1 */ V(12, 15, 1), + + /* 0000 0000 0100 ... */ + /* 0 */ V(15, 12, 1), /* 372 */ + /* 1 */ V(13, 14, 1), + + /* 0000 0000 0101 ... */ + /* 0 */ V(14, 13, 1), /* 374 */ + /* 1 */ V(11, 15, 1), + + /* 0000 0000 0111 ... */ + /* 0 */ V(12, 14, 1), /* 376 */ + /* 1 */ V(14, 12, 1), + + /* 0000 0001 1111 ... */ + /* 0 */ V(10, 14, 1), /* 378 */ + /* 1 */ V(0, 15, 1) +}; + +static +union huffpair const hufftab16[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 2), + /* 0100 */ V(1, 1, 4), + /* 0101 */ V(0, 1, 4), + /* 0110 */ V(1, 0, 3), + /* 0111 */ V(1, 0, 3), + /* 1000 */ V(0, 0, 1), + /* 1001 */ V(0, 0, 1), + /* 1010 */ V(0, 0, 1), + /* 1011 */ V(0, 0, 1), + /* 1100 */ V(0, 0, 1), + /* 1101 */ V(0, 0, 1), + /* 1110 */ V(0, 0, 1), + /* 1111 */ V(0, 0, 1), + + /* 0000 ... */ + /* 0000 */ PTR(68, 3), /* 16 */ + /* 0001 */ PTR(76, 3), + /* 0010 */ PTR(84, 2), + /* 0011 */ V(15, 15, 4), + /* 0100 */ PTR(88, 2), + /* 0101 */ PTR(92, 1), + /* 0110 */ PTR(94, 4), + /* 0111 */ V(15, 2, 4), + /* 1000 */ PTR(110, 1), + /* 1001 */ V(1, 15, 4), + /* 1010 */ V(15, 1, 4), + /* 1011 */ PTR(112, 4), + /* 1100 */ PTR(128, 4), + /* 1101 */ PTR(144, 4), + /* 1110 */ PTR(160, 4), + /* 1111 */ PTR(176, 4), + + /* 0001 ... */ + /* 0000 */ PTR(192, 4), /* 32 */ + /* 0001 */ PTR(208, 3), + /* 0010 */ PTR(216, 3), + /* 0011 */ PTR(224, 3), + /* 0100 */ PTR(232, 3), + /* 0101 */ PTR(240, 3), + /* 0110 */ PTR(248, 3), + /* 0111 */ PTR(256, 3), + /* 1000 */ PTR(264, 2), + /* 1001 */ PTR(268, 2), + /* 1010 */ PTR(272, 1), + /* 1011 */ PTR(274, 2), + /* 1100 */ PTR(278, 2), + /* 1101 */ PTR(282, 1), + /* 1110 */ V(5, 1, 4), + /* 1111 */ PTR(284, 1), + + /* 0010 ... */ + /* 0000 */ PTR(286, 1), /* 48 */ + /* 0001 */ PTR(288, 1), + /* 0010 */ PTR(290, 1), + /* 0011 */ V(1, 4, 4), + /* 0100 */ V(4, 1, 4), + /* 0101 */ PTR(292, 1), + /* 0110 */ V(2, 3, 4), + /* 0111 */ V(3, 2, 4), + /* 1000 */ V(1, 3, 3), + /* 1001 */ V(1, 3, 3), + /* 1010 */ V(3, 1, 3), + /* 1011 */ V(3, 1, 3), + /* 1100 */ V(0, 3, 4), + /* 1101 */ V(3, 0, 4), + /* 1110 */ V(2, 2, 3), + /* 1111 */ V(2, 2, 3), + + /* 0011 ... */ + /* 00 */ V(1, 2, 2), /* 64 */ + /* 01 */ V(2, 1, 2), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 000 */ V(14, 15, 3), /* 68 */ + /* 001 */ V(15, 14, 3), + /* 010 */ V(13, 15, 3), + /* 011 */ V(15, 13, 3), + /* 100 */ V(12, 15, 3), + /* 101 */ V(15, 12, 3), + /* 110 */ V(11, 15, 3), + /* 111 */ V(15, 11, 3), + + /* 0000 0001 ... */ + /* 000 */ V(10, 15, 2), /* 76 */ + /* 001 */ V(10, 15, 2), + /* 010 */ V(15, 10, 3), + /* 011 */ V(9, 15, 3), + /* 100 */ V(15, 9, 3), + /* 101 */ V(15, 8, 3), + /* 110 */ V(8, 15, 2), + /* 111 */ V(8, 15, 2), + + /* 0000 0010 ... */ + /* 00 */ V(7, 15, 2), /* 84 */ + /* 01 */ V(15, 7, 2), + /* 10 */ V(6, 15, 2), + /* 11 */ V(15, 6, 2), + + /* 0000 0100 ... */ + /* 00 */ V(5, 15, 2), /* 88 */ + /* 01 */ V(15, 5, 2), + /* 10 */ V(4, 15, 1), + /* 11 */ V(4, 15, 1), + + /* 0000 0101 ... */ + /* 0 */ V(15, 4, 1), /* 92 */ + /* 1 */ V(15, 3, 1), + + /* 0000 0110 ... */ + /* 0000 */ V(15, 0, 1), /* 94 */ + /* 0001 */ V(15, 0, 1), + /* 0010 */ V(15, 0, 1), + /* 0011 */ V(15, 0, 1), + /* 0100 */ V(15, 0, 1), + /* 0101 */ V(15, 0, 1), + /* 0110 */ V(15, 0, 1), + /* 0111 */ V(15, 0, 1), + /* 1000 */ V(3, 15, 2), + /* 1001 */ V(3, 15, 2), + /* 1010 */ V(3, 15, 2), + /* 1011 */ V(3, 15, 2), + /* 1100 */ PTR(294, 4), + /* 1101 */ PTR(310, 3), + /* 1110 */ PTR(318, 3), + /* 1111 */ PTR(326, 3), + + /* 0000 1000 ... */ + /* 0 */ V(2, 15, 1), /* 110 */ + /* 1 */ V(0, 15, 1), + + /* 0000 1011 ... */ + /* 0000 */ PTR(334, 2), /* 112 */ + /* 0001 */ PTR(338, 2), + /* 0010 */ PTR(342, 2), + /* 0011 */ PTR(346, 1), + /* 0100 */ PTR(348, 2), + /* 0101 */ PTR(352, 2), + /* 0110 */ PTR(356, 1), + /* 0111 */ PTR(358, 2), + /* 1000 */ PTR(362, 2), + /* 1001 */ PTR(366, 2), + /* 1010 */ PTR(370, 2), + /* 1011 */ V(14, 3, 4), + /* 1100 */ PTR(374, 1), + /* 1101 */ PTR(376, 1), + /* 1110 */ PTR(378, 1), + /* 1111 */ PTR(380, 1), + + /* 0000 1100 ... */ + /* 0000 */ PTR(382, 1), /* 128 */ + /* 0001 */ PTR(384, 1), + /* 0010 */ PTR(386, 1), + /* 0011 */ V(0, 13, 4), + /* 0100 */ PTR(388, 1), + /* 0101 */ PTR(390, 1), + /* 0110 */ PTR(392, 1), + /* 0111 */ V(3, 12, 4), + /* 1000 */ PTR(394, 1), + /* 1001 */ V(1, 12, 4), + /* 1010 */ V(12, 0, 4), + /* 1011 */ PTR(396, 1), + /* 1100 */ V(14, 2, 3), + /* 1101 */ V(14, 2, 3), + /* 1110 */ V(2, 14, 4), + /* 1111 */ V(1, 14, 4), + + /* 0000 1101 ... */ + /* 0000 */ V(13, 3, 4), /* 144 */ + /* 0001 */ V(2, 13, 4), + /* 0010 */ V(13, 2, 4), + /* 0011 */ V(13, 1, 4), + /* 0100 */ V(3, 11, 4), + /* 0101 */ PTR(398, 1), + /* 0110 */ V(1, 13, 3), + /* 0111 */ V(1, 13, 3), + /* 1000 */ V(12, 4, 4), + /* 1001 */ V(6, 11, 4), + /* 1010 */ V(12, 3, 4), + /* 1011 */ V(10, 7, 4), + /* 1100 */ V(2, 12, 3), + /* 1101 */ V(2, 12, 3), + /* 1110 */ V(12, 2, 4), + /* 1111 */ V(11, 5, 4), + + /* 0000 1110 ... */ + /* 0000 */ V(12, 1, 4), /* 160 */ + /* 0001 */ V(0, 12, 4), + /* 0010 */ V(4, 11, 4), + /* 0011 */ V(11, 4, 4), + /* 0100 */ V(6, 10, 4), + /* 0101 */ V(10, 6, 4), + /* 0110 */ V(11, 3, 3), + /* 0111 */ V(11, 3, 3), + /* 1000 */ V(5, 10, 4), + /* 1001 */ V(10, 5, 4), + /* 1010 */ V(2, 11, 3), + /* 1011 */ V(2, 11, 3), + /* 1100 */ V(11, 2, 3), + /* 1101 */ V(11, 2, 3), + /* 1110 */ V(1, 11, 3), + /* 1111 */ V(1, 11, 3), + + /* 0000 1111 ... */ + /* 0000 */ V(11, 1, 3), /* 176 */ + /* 0001 */ V(11, 1, 3), + /* 0010 */ V(0, 11, 4), + /* 0011 */ V(11, 0, 4), + /* 0100 */ V(6, 9, 4), + /* 0101 */ V(9, 6, 4), + /* 0110 */ V(4, 10, 4), + /* 0111 */ V(10, 4, 4), + /* 1000 */ V(7, 8, 4), + /* 1001 */ V(8, 7, 4), + /* 1010 */ V(10, 3, 3), + /* 1011 */ V(10, 3, 3), + /* 1100 */ V(3, 10, 4), + /* 1101 */ V(5, 9, 4), + /* 1110 */ V(2, 10, 3), + /* 1111 */ V(2, 10, 3), + + /* 0001 0000 ... */ + /* 0000 */ V(9, 5, 4), /* 192 */ + /* 0001 */ V(6, 8, 4), + /* 0010 */ V(10, 1, 3), + /* 0011 */ V(10, 1, 3), + /* 0100 */ V(8, 6, 4), + /* 0101 */ V(7, 7, 4), + /* 0110 */ V(9, 4, 3), + /* 0111 */ V(9, 4, 3), + /* 1000 */ V(4, 9, 4), + /* 1001 */ V(5, 7, 4), + /* 1010 */ V(6, 7, 3), + /* 1011 */ V(6, 7, 3), + /* 1100 */ V(10, 2, 2), + /* 1101 */ V(10, 2, 2), + /* 1110 */ V(10, 2, 2), + /* 1111 */ V(10, 2, 2), + + /* 0001 0001 ... */ + /* 000 */ V(1, 10, 2), /* 208 */ + /* 001 */ V(1, 10, 2), + /* 010 */ V(0, 10, 3), + /* 011 */ V(10, 0, 3), + /* 100 */ V(3, 9, 3), + /* 101 */ V(9, 3, 3), + /* 110 */ V(5, 8, 3), + /* 111 */ V(8, 5, 3), + + /* 0001 0010 ... */ + /* 000 */ V(2, 9, 2), /* 216 */ + /* 001 */ V(2, 9, 2), + /* 010 */ V(9, 2, 2), + /* 011 */ V(9, 2, 2), + /* 100 */ V(7, 6, 3), + /* 101 */ V(0, 9, 3), + /* 110 */ V(1, 9, 2), + /* 111 */ V(1, 9, 2), + + /* 0001 0011 ... */ + /* 000 */ V(9, 1, 2), /* 224 */ + /* 001 */ V(9, 1, 2), + /* 010 */ V(9, 0, 3), + /* 011 */ V(4, 8, 3), + /* 100 */ V(8, 4, 3), + /* 101 */ V(7, 5, 3), + /* 110 */ V(3, 8, 3), + /* 111 */ V(8, 3, 3), + + /* 0001 0100 ... */ + /* 000 */ V(6, 6, 3), /* 232 */ + /* 001 */ V(2, 8, 3), + /* 010 */ V(8, 2, 2), + /* 011 */ V(8, 2, 2), + /* 100 */ V(4, 7, 3), + /* 101 */ V(7, 4, 3), + /* 110 */ V(1, 8, 2), + /* 111 */ V(1, 8, 2), + + /* 0001 0101 ... */ + /* 000 */ V(8, 1, 2), /* 240 */ + /* 001 */ V(8, 1, 2), + /* 010 */ V(8, 0, 2), + /* 011 */ V(8, 0, 2), + /* 100 */ V(0, 8, 3), + /* 101 */ V(5, 6, 3), + /* 110 */ V(3, 7, 2), + /* 111 */ V(3, 7, 2), + + /* 0001 0110 ... */ + /* 000 */ V(7, 3, 2), /* 248 */ + /* 001 */ V(7, 3, 2), + /* 010 */ V(6, 5, 3), + /* 011 */ V(4, 6, 3), + /* 100 */ V(2, 7, 2), + /* 101 */ V(2, 7, 2), + /* 110 */ V(7, 2, 2), + /* 111 */ V(7, 2, 2), + + /* 0001 0111 ... */ + /* 000 */ V(6, 4, 3), /* 256 */ + /* 001 */ V(5, 5, 3), + /* 010 */ V(0, 7, 2), + /* 011 */ V(0, 7, 2), + /* 100 */ V(1, 7, 1), + /* 101 */ V(1, 7, 1), + /* 110 */ V(1, 7, 1), + /* 111 */ V(1, 7, 1), + + /* 0001 1000 ... */ + /* 00 */ V(7, 1, 1), /* 264 */ + /* 01 */ V(7, 1, 1), + /* 10 */ V(7, 0, 2), + /* 11 */ V(3, 6, 2), + + /* 0001 1001 ... */ + /* 00 */ V(6, 3, 2), /* 268 */ + /* 01 */ V(4, 5, 2), + /* 10 */ V(5, 4, 2), + /* 11 */ V(2, 6, 2), + + /* 0001 1010 ... */ + /* 0 */ V(6, 2, 1), /* 272 */ + /* 1 */ V(1, 6, 1), + + /* 0001 1011 ... */ + /* 00 */ V(6, 1, 1), /* 274 */ + /* 01 */ V(6, 1, 1), + /* 10 */ V(0, 6, 2), + /* 11 */ V(6, 0, 2), + + /* 0001 1100 ... */ + /* 00 */ V(5, 3, 1), /* 278 */ + /* 01 */ V(5, 3, 1), + /* 10 */ V(3, 5, 2), + /* 11 */ V(4, 4, 2), + + /* 0001 1101 ... */ + /* 0 */ V(2, 5, 1), /* 282 */ + /* 1 */ V(5, 2, 1), + + /* 0001 1111 ... */ + /* 0 */ V(1, 5, 1), /* 284 */ + /* 1 */ V(0, 5, 1), + + /* 0010 0000 ... */ + /* 0 */ V(3, 4, 1), /* 286 */ + /* 1 */ V(4, 3, 1), + + /* 0010 0001 ... */ + /* 0 */ V(5, 0, 1), /* 288 */ + /* 1 */ V(2, 4, 1), + + /* 0010 0010 ... */ + /* 0 */ V(4, 2, 1), /* 290 */ + /* 1 */ V(3, 3, 1), + + /* 0010 0101 ... */ + /* 0 */ V(0, 4, 1), /* 292 */ + /* 1 */ V(4, 0, 1), + + /* 0000 0110 1100 ... */ + /* 0000 */ V(12, 14, 4), /* 294 */ + /* 0001 */ PTR(400, 1), + /* 0010 */ V(13, 14, 3), + /* 0011 */ V(13, 14, 3), + /* 0100 */ V(14, 9, 3), + /* 0101 */ V(14, 9, 3), + /* 0110 */ V(14, 10, 4), + /* 0111 */ V(13, 9, 4), + /* 1000 */ V(14, 14, 2), + /* 1001 */ V(14, 14, 2), + /* 1010 */ V(14, 14, 2), + /* 1011 */ V(14, 14, 2), + /* 1100 */ V(14, 13, 3), + /* 1101 */ V(14, 13, 3), + /* 1110 */ V(14, 11, 3), + /* 1111 */ V(14, 11, 3), + + /* 0000 0110 1101 ... */ + /* 000 */ V(11, 14, 2), /* 310 */ + /* 001 */ V(11, 14, 2), + /* 010 */ V(12, 13, 2), + /* 011 */ V(12, 13, 2), + /* 100 */ V(13, 12, 3), + /* 101 */ V(13, 11, 3), + /* 110 */ V(10, 14, 2), + /* 111 */ V(10, 14, 2), + + /* 0000 0110 1110 ... */ + /* 000 */ V(12, 12, 2), /* 318 */ + /* 001 */ V(12, 12, 2), + /* 010 */ V(10, 13, 3), + /* 011 */ V(13, 10, 3), + /* 100 */ V(7, 14, 3), + /* 101 */ V(10, 12, 3), + /* 110 */ V(12, 10, 2), + /* 111 */ V(12, 10, 2), + + /* 0000 0110 1111 ... */ + /* 000 */ V(12, 9, 3), /* 326 */ + /* 001 */ V(7, 13, 3), + /* 010 */ V(5, 14, 2), + /* 011 */ V(5, 14, 2), + /* 100 */ V(11, 13, 1), + /* 101 */ V(11, 13, 1), + /* 110 */ V(11, 13, 1), + /* 111 */ V(11, 13, 1), + + /* 0000 1011 0000 ... */ + /* 00 */ V(9, 14, 1), /* 334 */ + /* 01 */ V(9, 14, 1), + /* 10 */ V(11, 12, 2), + /* 11 */ V(12, 11, 2), + + /* 0000 1011 0001 ... */ + /* 00 */ V(8, 14, 2), /* 338 */ + /* 01 */ V(14, 8, 2), + /* 10 */ V(9, 13, 2), + /* 11 */ V(14, 7, 2), + + /* 0000 1011 0010 ... */ + /* 00 */ V(11, 11, 2), /* 342 */ + /* 01 */ V(8, 13, 2), + /* 10 */ V(13, 8, 2), + /* 11 */ V(6, 14, 2), + + /* 0000 1011 0011 ... */ + /* 0 */ V(14, 6, 1), /* 346 */ + /* 1 */ V(9, 12, 1), + + /* 0000 1011 0100 ... */ + /* 00 */ V(10, 11, 2), /* 348 */ + /* 01 */ V(11, 10, 2), + /* 10 */ V(14, 5, 2), + /* 11 */ V(13, 7, 2), + + /* 0000 1011 0101 ... */ + /* 00 */ V(4, 14, 1), /* 352 */ + /* 01 */ V(4, 14, 1), + /* 10 */ V(14, 4, 2), + /* 11 */ V(8, 12, 2), + + /* 0000 1011 0110 ... */ + /* 0 */ V(12, 8, 1), /* 356 */ + /* 1 */ V(3, 14, 1), + + /* 0000 1011 0111 ... */ + /* 00 */ V(6, 13, 1), /* 358 */ + /* 01 */ V(6, 13, 1), + /* 10 */ V(13, 6, 2), + /* 11 */ V(9, 11, 2), + + /* 0000 1011 1000 ... */ + /* 00 */ V(11, 9, 2), /* 362 */ + /* 01 */ V(10, 10, 2), + /* 10 */ V(14, 1, 1), + /* 11 */ V(14, 1, 1), + + /* 0000 1011 1001 ... */ + /* 00 */ V(13, 4, 1), /* 366 */ + /* 01 */ V(13, 4, 1), + /* 10 */ V(11, 8, 2), + /* 11 */ V(10, 9, 2), + + /* 0000 1011 1010 ... */ + /* 00 */ V(7, 11, 1), /* 370 */ + /* 01 */ V(7, 11, 1), + /* 10 */ V(11, 7, 2), + /* 11 */ V(13, 0, 2), + + /* 0000 1011 1100 ... */ + /* 0 */ V(0, 14, 1), /* 374 */ + /* 1 */ V(14, 0, 1), + + /* 0000 1011 1101 ... */ + /* 0 */ V(5, 13, 1), /* 376 */ + /* 1 */ V(13, 5, 1), + + /* 0000 1011 1110 ... */ + /* 0 */ V(7, 12, 1), /* 378 */ + /* 1 */ V(12, 7, 1), + + /* 0000 1011 1111 ... */ + /* 0 */ V(4, 13, 1), /* 380 */ + /* 1 */ V(8, 11, 1), + + /* 0000 1100 0000 ... */ + /* 0 */ V(9, 10, 1), /* 382 */ + /* 1 */ V(6, 12, 1), + + /* 0000 1100 0001 ... */ + /* 0 */ V(12, 6, 1), /* 384 */ + /* 1 */ V(3, 13, 1), + + /* 0000 1100 0010 ... */ + /* 0 */ V(5, 12, 1), /* 386 */ + /* 1 */ V(12, 5, 1), + + /* 0000 1100 0100 ... */ + /* 0 */ V(8, 10, 1), /* 388 */ + /* 1 */ V(10, 8, 1), + + /* 0000 1100 0101 ... */ + /* 0 */ V(9, 9, 1), /* 390 */ + /* 1 */ V(4, 12, 1), + + /* 0000 1100 0110 ... */ + /* 0 */ V(11, 6, 1), /* 392 */ + /* 1 */ V(7, 10, 1), + + /* 0000 1100 1000 ... */ + /* 0 */ V(5, 11, 1), /* 394 */ + /* 1 */ V(8, 9, 1), + + /* 0000 1100 1011 ... */ + /* 0 */ V(9, 8, 1), /* 396 */ + /* 1 */ V(7, 9, 1), + + /* 0000 1101 0101 ... */ + /* 0 */ V(9, 7, 1), /* 398 */ + /* 1 */ V(8, 8, 1), + + /* 0000 0110 1100 0001 ... */ + /* 0 */ V(14, 12, 1), /* 400 */ + /* 1 */ V(13, 13, 1) +}; + +static +union huffpair const hufftab24[] = { + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ V(15, 15, 4), + /* 0100 */ PTR(64, 4), + /* 0101 */ PTR(80, 4), + /* 0110 */ PTR(96, 4), + /* 0111 */ PTR(112, 4), + /* 1000 */ PTR(128, 4), + /* 1001 */ PTR(144, 4), + /* 1010 */ PTR(160, 3), + /* 1011 */ PTR(168, 2), + /* 1100 */ V(1, 1, 4), + /* 1101 */ V(0, 1, 4), + /* 1110 */ V(1, 0, 4), + /* 1111 */ V(0, 0, 4), + + /* 0000 ... */ + /* 0000 */ V(14, 15, 4), /* 16 */ + /* 0001 */ V(15, 14, 4), + /* 0010 */ V(13, 15, 4), + /* 0011 */ V(15, 13, 4), + /* 0100 */ V(12, 15, 4), + /* 0101 */ V(15, 12, 4), + /* 0110 */ V(11, 15, 4), + /* 0111 */ V(15, 11, 4), + /* 1000 */ V(15, 10, 3), + /* 1001 */ V(15, 10, 3), + /* 1010 */ V(10, 15, 4), + /* 1011 */ V(9, 15, 4), + /* 1100 */ V(15, 9, 3), + /* 1101 */ V(15, 9, 3), + /* 1110 */ V(15, 8, 3), + /* 1111 */ V(15, 8, 3), + + /* 0001 ... */ + /* 0000 */ V(8, 15, 4), /* 32 */ + /* 0001 */ V(7, 15, 4), + /* 0010 */ V(15, 7, 3), + /* 0011 */ V(15, 7, 3), + /* 0100 */ V(6, 15, 3), + /* 0101 */ V(6, 15, 3), + /* 0110 */ V(15, 6, 3), + /* 0111 */ V(15, 6, 3), + /* 1000 */ V(5, 15, 3), + /* 1001 */ V(5, 15, 3), + /* 1010 */ V(15, 5, 3), + /* 1011 */ V(15, 5, 3), + /* 1100 */ V(4, 15, 3), + /* 1101 */ V(4, 15, 3), + /* 1110 */ V(15, 4, 3), + /* 1111 */ V(15, 4, 3), + + /* 0010 ... */ + /* 0000 */ V(3, 15, 3), /* 48 */ + /* 0001 */ V(3, 15, 3), + /* 0010 */ V(15, 3, 3), + /* 0011 */ V(15, 3, 3), + /* 0100 */ V(2, 15, 3), + /* 0101 */ V(2, 15, 3), + /* 0110 */ V(15, 2, 3), + /* 0111 */ V(15, 2, 3), + /* 1000 */ V(15, 1, 3), + /* 1001 */ V(15, 1, 3), + /* 1010 */ V(1, 15, 4), + /* 1011 */ V(15, 0, 4), + /* 1100 */ PTR(172, 3), + /* 1101 */ PTR(180, 3), + /* 1110 */ PTR(188, 3), + /* 1111 */ PTR(196, 3), + + /* 0100 ... */ + /* 0000 */ PTR(204, 4), /* 64 */ + /* 0001 */ PTR(220, 3), + /* 0010 */ PTR(228, 3), + /* 0011 */ PTR(236, 3), + /* 0100 */ PTR(244, 2), + /* 0101 */ PTR(248, 2), + /* 0110 */ PTR(252, 2), + /* 0111 */ PTR(256, 2), + /* 1000 */ PTR(260, 2), + /* 1001 */ PTR(264, 2), + /* 1010 */ PTR(268, 2), + /* 1011 */ PTR(272, 2), + /* 1100 */ PTR(276, 2), + /* 1101 */ PTR(280, 3), + /* 1110 */ PTR(288, 2), + /* 1111 */ PTR(292, 2), + + /* 0101 ... */ + /* 0000 */ PTR(296, 2), /* 80 */ + /* 0001 */ PTR(300, 3), + /* 0010 */ PTR(308, 2), + /* 0011 */ PTR(312, 3), + /* 0100 */ PTR(320, 1), + /* 0101 */ PTR(322, 2), + /* 0110 */ PTR(326, 2), + /* 0111 */ PTR(330, 1), + /* 1000 */ PTR(332, 2), + /* 1001 */ PTR(336, 1), + /* 1010 */ PTR(338, 1), + /* 1011 */ PTR(340, 1), + /* 1100 */ PTR(342, 1), + /* 1101 */ PTR(344, 1), + /* 1110 */ PTR(346, 1), + /* 1111 */ PTR(348, 1), + + /* 0110 ... */ + /* 0000 */ PTR(350, 1), /* 96 */ + /* 0001 */ PTR(352, 1), + /* 0010 */ PTR(354, 1), + /* 0011 */ PTR(356, 1), + /* 0100 */ PTR(358, 1), + /* 0101 */ PTR(360, 1), + /* 0110 */ PTR(362, 1), + /* 0111 */ PTR(364, 1), + /* 1000 */ PTR(366, 1), + /* 1001 */ PTR(368, 1), + /* 1010 */ PTR(370, 2), + /* 1011 */ PTR(374, 1), + /* 1100 */ PTR(376, 2), + /* 1101 */ V(7, 3, 4), + /* 1110 */ PTR(380, 1), + /* 1111 */ V(7, 2, 4), + + /* 0111 ... */ + /* 0000 */ V(4, 6, 4), /* 112 */ + /* 0001 */ V(6, 4, 4), + /* 0010 */ V(5, 5, 4), + /* 0011 */ V(7, 1, 4), + /* 0100 */ V(3, 6, 4), + /* 0101 */ V(6, 3, 4), + /* 0110 */ V(4, 5, 4), + /* 0111 */ V(5, 4, 4), + /* 1000 */ V(2, 6, 4), + /* 1001 */ V(6, 2, 4), + /* 1010 */ V(1, 6, 4), + /* 1011 */ V(6, 1, 4), + /* 1100 */ PTR(382, 1), + /* 1101 */ V(3, 5, 4), + /* 1110 */ V(5, 3, 4), + /* 1111 */ V(4, 4, 4), + + /* 1000 ... */ + /* 0000 */ V(2, 5, 4), /* 128 */ + /* 0001 */ V(5, 2, 4), + /* 0010 */ V(1, 5, 4), + /* 0011 */ PTR(384, 1), + /* 0100 */ V(5, 1, 3), + /* 0101 */ V(5, 1, 3), + /* 0110 */ V(3, 4, 4), + /* 0111 */ V(4, 3, 4), + /* 1000 */ V(2, 4, 3), + /* 1001 */ V(2, 4, 3), + /* 1010 */ V(4, 2, 3), + /* 1011 */ V(4, 2, 3), + /* 1100 */ V(3, 3, 3), + /* 1101 */ V(3, 3, 3), + /* 1110 */ V(1, 4, 3), + /* 1111 */ V(1, 4, 3), + + /* 1001 ... */ + /* 0000 */ V(4, 1, 3), /* 144 */ + /* 0001 */ V(4, 1, 3), + /* 0010 */ V(0, 4, 4), + /* 0011 */ V(4, 0, 4), + /* 0100 */ V(2, 3, 3), + /* 0101 */ V(2, 3, 3), + /* 0110 */ V(3, 2, 3), + /* 0111 */ V(3, 2, 3), + /* 1000 */ V(1, 3, 2), + /* 1001 */ V(1, 3, 2), + /* 1010 */ V(1, 3, 2), + /* 1011 */ V(1, 3, 2), + /* 1100 */ V(3, 1, 2), + /* 1101 */ V(3, 1, 2), + /* 1110 */ V(3, 1, 2), + /* 1111 */ V(3, 1, 2), + + /* 1010 ... */ + /* 000 */ V(0, 3, 3), /* 160 */ + /* 001 */ V(3, 0, 3), + /* 010 */ V(2, 2, 2), + /* 011 */ V(2, 2, 2), + /* 100 */ V(1, 2, 1), + /* 101 */ V(1, 2, 1), + /* 110 */ V(1, 2, 1), + /* 111 */ V(1, 2, 1), + + /* 1011 ... */ + /* 00 */ V(2, 1, 1), /* 168 */ + /* 01 */ V(2, 1, 1), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0010 1100 ... */ + /* 000 */ V(0, 15, 1), /* 172 */ + /* 001 */ V(0, 15, 1), + /* 010 */ V(0, 15, 1), + /* 011 */ V(0, 15, 1), + /* 100 */ V(14, 14, 3), + /* 101 */ V(13, 14, 3), + /* 110 */ V(14, 13, 3), + /* 111 */ V(12, 14, 3), + + /* 0010 1101 ... */ + /* 000 */ V(14, 12, 3), /* 180 */ + /* 001 */ V(13, 13, 3), + /* 010 */ V(11, 14, 3), + /* 011 */ V(14, 11, 3), + /* 100 */ V(12, 13, 3), + /* 101 */ V(13, 12, 3), + /* 110 */ V(10, 14, 3), + /* 111 */ V(14, 10, 3), + + /* 0010 1110 ... */ + /* 000 */ V(11, 13, 3), /* 188 */ + /* 001 */ V(13, 11, 3), + /* 010 */ V(12, 12, 3), + /* 011 */ V(9, 14, 3), + /* 100 */ V(14, 9, 3), + /* 101 */ V(10, 13, 3), + /* 110 */ V(13, 10, 3), + /* 111 */ V(11, 12, 3), + + /* 0010 1111 ... */ + /* 000 */ V(12, 11, 3), /* 196 */ + /* 001 */ V(8, 14, 3), + /* 010 */ V(14, 8, 3), + /* 011 */ V(9, 13, 3), + /* 100 */ V(13, 9, 3), + /* 101 */ V(7, 14, 3), + /* 110 */ V(14, 7, 3), + /* 111 */ V(10, 12, 3), + + /* 0100 0000 ... */ + /* 0000 */ V(12, 10, 3), /* 204 */ + /* 0001 */ V(12, 10, 3), + /* 0010 */ V(11, 11, 3), + /* 0011 */ V(11, 11, 3), + /* 0100 */ V(8, 13, 3), + /* 0101 */ V(8, 13, 3), + /* 0110 */ V(13, 8, 3), + /* 0111 */ V(13, 8, 3), + /* 1000 */ V(0, 14, 4), + /* 1001 */ V(14, 0, 4), + /* 1010 */ V(0, 13, 3), + /* 1011 */ V(0, 13, 3), + /* 1100 */ V(14, 6, 2), + /* 1101 */ V(14, 6, 2), + /* 1110 */ V(14, 6, 2), + /* 1111 */ V(14, 6, 2), + + /* 0100 0001 ... */ + /* 000 */ V(6, 14, 3), /* 220 */ + /* 001 */ V(9, 12, 3), + /* 010 */ V(12, 9, 2), + /* 011 */ V(12, 9, 2), + /* 100 */ V(5, 14, 2), + /* 101 */ V(5, 14, 2), + /* 110 */ V(11, 10, 2), + /* 111 */ V(11, 10, 2), + + /* 0100 0010 ... */ + /* 000 */ V(14, 5, 2), /* 228 */ + /* 001 */ V(14, 5, 2), + /* 010 */ V(10, 11, 3), + /* 011 */ V(7, 13, 3), + /* 100 */ V(13, 7, 2), + /* 101 */ V(13, 7, 2), + /* 110 */ V(14, 4, 2), + /* 111 */ V(14, 4, 2), + + /* 0100 0011 ... */ + /* 000 */ V(8, 12, 2), /* 236 */ + /* 001 */ V(8, 12, 2), + /* 010 */ V(12, 8, 2), + /* 011 */ V(12, 8, 2), + /* 100 */ V(4, 14, 3), + /* 101 */ V(2, 14, 3), + /* 110 */ V(3, 14, 2), + /* 111 */ V(3, 14, 2), + + /* 0100 0100 ... */ + /* 00 */ V(6, 13, 2), /* 244 */ + /* 01 */ V(13, 6, 2), + /* 10 */ V(14, 3, 2), + /* 11 */ V(9, 11, 2), + + /* 0100 0101 ... */ + /* 00 */ V(11, 9, 2), /* 248 */ + /* 01 */ V(10, 10, 2), + /* 10 */ V(14, 2, 2), + /* 11 */ V(1, 14, 2), + + /* 0100 0110 ... */ + /* 00 */ V(14, 1, 2), /* 252 */ + /* 01 */ V(5, 13, 2), + /* 10 */ V(13, 5, 2), + /* 11 */ V(7, 12, 2), + + /* 0100 0111 ... */ + /* 00 */ V(12, 7, 2), /* 256 */ + /* 01 */ V(4, 13, 2), + /* 10 */ V(8, 11, 2), + /* 11 */ V(11, 8, 2), + + /* 0100 1000 ... */ + /* 00 */ V(13, 4, 2), /* 260 */ + /* 01 */ V(9, 10, 2), + /* 10 */ V(10, 9, 2), + /* 11 */ V(6, 12, 2), + + /* 0100 1001 ... */ + /* 00 */ V(12, 6, 2), /* 264 */ + /* 01 */ V(3, 13, 2), + /* 10 */ V(13, 3, 2), + /* 11 */ V(2, 13, 2), + + /* 0100 1010 ... */ + /* 00 */ V(13, 2, 2), /* 268 */ + /* 01 */ V(1, 13, 2), + /* 10 */ V(7, 11, 2), + /* 11 */ V(11, 7, 2), + + /* 0100 1011 ... */ + /* 00 */ V(13, 1, 2), /* 272 */ + /* 01 */ V(5, 12, 2), + /* 10 */ V(12, 5, 2), + /* 11 */ V(8, 10, 2), + + /* 0100 1100 ... */ + /* 00 */ V(10, 8, 2), /* 276 */ + /* 01 */ V(9, 9, 2), + /* 10 */ V(4, 12, 2), + /* 11 */ V(12, 4, 2), + + /* 0100 1101 ... */ + /* 000 */ V(6, 11, 2), /* 280 */ + /* 001 */ V(6, 11, 2), + /* 010 */ V(11, 6, 2), + /* 011 */ V(11, 6, 2), + /* 100 */ V(13, 0, 3), + /* 101 */ V(0, 12, 3), + /* 110 */ V(3, 12, 2), + /* 111 */ V(3, 12, 2), + + /* 0100 1110 ... */ + /* 00 */ V(12, 3, 2), /* 288 */ + /* 01 */ V(7, 10, 2), + /* 10 */ V(10, 7, 2), + /* 11 */ V(2, 12, 2), + + /* 0100 1111 ... */ + /* 00 */ V(12, 2, 2), /* 292 */ + /* 01 */ V(5, 11, 2), + /* 10 */ V(11, 5, 2), + /* 11 */ V(1, 12, 2), + + /* 0101 0000 ... */ + /* 00 */ V(8, 9, 2), /* 296 */ + /* 01 */ V(9, 8, 2), + /* 10 */ V(12, 1, 2), + /* 11 */ V(4, 11, 2), + + /* 0101 0001 ... */ + /* 000 */ V(12, 0, 3), /* 300 */ + /* 001 */ V(0, 11, 3), + /* 010 */ V(3, 11, 2), + /* 011 */ V(3, 11, 2), + /* 100 */ V(11, 0, 3), + /* 101 */ V(0, 10, 3), + /* 110 */ V(1, 10, 2), + /* 111 */ V(1, 10, 2), + + /* 0101 0010 ... */ + /* 00 */ V(11, 4, 1), /* 308 */ + /* 01 */ V(11, 4, 1), + /* 10 */ V(6, 10, 2), + /* 11 */ V(10, 6, 2), + + /* 0101 0011 ... */ + /* 000 */ V(7, 9, 2), /* 312 */ + /* 001 */ V(7, 9, 2), + /* 010 */ V(9, 7, 2), + /* 011 */ V(9, 7, 2), + /* 100 */ V(10, 0, 3), + /* 101 */ V(0, 9, 3), + /* 110 */ V(9, 0, 2), + /* 111 */ V(9, 0, 2), + + /* 0101 0100 ... */ + /* 0 */ V(11, 3, 1), /* 320 */ + /* 1 */ V(8, 8, 1), + + /* 0101 0101 ... */ + /* 00 */ V(2, 11, 2), /* 322 */ + /* 01 */ V(5, 10, 2), + /* 10 */ V(11, 2, 1), + /* 11 */ V(11, 2, 1), + + /* 0101 0110 ... */ + /* 00 */ V(10, 5, 2), /* 326 */ + /* 01 */ V(1, 11, 2), + /* 10 */ V(11, 1, 2), + /* 11 */ V(6, 9, 2), + + /* 0101 0111 ... */ + /* 0 */ V(9, 6, 1), /* 330 */ + /* 1 */ V(10, 4, 1), + + /* 0101 1000 ... */ + /* 00 */ V(4, 10, 2), /* 332 */ + /* 01 */ V(7, 8, 2), + /* 10 */ V(8, 7, 1), + /* 11 */ V(8, 7, 1), + + /* 0101 1001 ... */ + /* 0 */ V(3, 10, 1), /* 336 */ + /* 1 */ V(10, 3, 1), + + /* 0101 1010 ... */ + /* 0 */ V(5, 9, 1), /* 338 */ + /* 1 */ V(9, 5, 1), + + /* 0101 1011 ... */ + /* 0 */ V(2, 10, 1), /* 340 */ + /* 1 */ V(10, 2, 1), + + /* 0101 1100 ... */ + /* 0 */ V(10, 1, 1), /* 342 */ + /* 1 */ V(6, 8, 1), + + /* 0101 1101 ... */ + /* 0 */ V(8, 6, 1), /* 344 */ + /* 1 */ V(7, 7, 1), + + /* 0101 1110 ... */ + /* 0 */ V(4, 9, 1), /* 346 */ + /* 1 */ V(9, 4, 1), + + /* 0101 1111 ... */ + /* 0 */ V(3, 9, 1), /* 348 */ + /* 1 */ V(9, 3, 1), + + /* 0110 0000 ... */ + /* 0 */ V(5, 8, 1), /* 350 */ + /* 1 */ V(8, 5, 1), + + /* 0110 0001 ... */ + /* 0 */ V(2, 9, 1), /* 352 */ + /* 1 */ V(6, 7, 1), + + /* 0110 0010 ... */ + /* 0 */ V(7, 6, 1), /* 354 */ + /* 1 */ V(9, 2, 1), + + /* 0110 0011 ... */ + /* 0 */ V(1, 9, 1), /* 356 */ + /* 1 */ V(9, 1, 1), + + /* 0110 0100 ... */ + /* 0 */ V(4, 8, 1), /* 358 */ + /* 1 */ V(8, 4, 1), + + /* 0110 0101 ... */ + /* 0 */ V(5, 7, 1), /* 360 */ + /* 1 */ V(7, 5, 1), + + /* 0110 0110 ... */ + /* 0 */ V(3, 8, 1), /* 362 */ + /* 1 */ V(8, 3, 1), + + /* 0110 0111 ... */ + /* 0 */ V(6, 6, 1), /* 364 */ + /* 1 */ V(2, 8, 1), + + /* 0110 1000 ... */ + /* 0 */ V(8, 2, 1), /* 366 */ + /* 1 */ V(1, 8, 1), + + /* 0110 1001 ... */ + /* 0 */ V(4, 7, 1), /* 368 */ + /* 1 */ V(7, 4, 1), + + /* 0110 1010 ... */ + /* 00 */ V(8, 1, 1), /* 370 */ + /* 01 */ V(8, 1, 1), + /* 10 */ V(0, 8, 2), + /* 11 */ V(8, 0, 2), + + /* 0110 1011 ... */ + /* 0 */ V(5, 6, 1), /* 374 */ + /* 1 */ V(6, 5, 1), + + /* 0110 1100 ... */ + /* 00 */ V(1, 7, 1), /* 376 */ + /* 01 */ V(1, 7, 1), + /* 10 */ V(0, 7, 2), + /* 11 */ V(7, 0, 2), + + /* 0110 1110 ... */ + /* 0 */ V(3, 7, 1), /* 380 */ + /* 1 */ V(2, 7, 1), + + /* 0111 1100 ... */ + /* 0 */ V(0, 6, 1), /* 382 */ + /* 1 */ V(6, 0, 1), + + /* 1000 0011 ... */ + /* 0 */ V(0, 5, 1), /* 384 */ + /* 1 */ V(5, 0, 1) +}; + +# undef V +# undef PTR + +/* external tables */ + +union huffquad const *const mad_huff_quad_table[2] = { hufftabA, hufftabB }; + +struct hufftable const mad_huff_pair_table[32] = { + /* 0 */ { hufftab0, 0, 0 }, + /* 1 */ { hufftab1, 0, 3 }, + /* 2 */ { hufftab2, 0, 3 }, + /* 3 */ { hufftab3, 0, 3 }, + /* 4 */ { 0 /* not used */ }, + /* 5 */ { hufftab5, 0, 3 }, + /* 6 */ { hufftab6, 0, 4 }, + /* 7 */ { hufftab7, 0, 4 }, + /* 8 */ { hufftab8, 0, 4 }, + /* 9 */ { hufftab9, 0, 4 }, + /* 10 */ { hufftab10, 0, 4 }, + /* 11 */ { hufftab11, 0, 4 }, + /* 12 */ { hufftab12, 0, 4 }, + /* 13 */ { hufftab13, 0, 4 }, + /* 14 */ { 0 /* not used */ }, + /* 15 */ { hufftab15, 0, 4 }, + /* 16 */ { hufftab16, 1, 4 }, + /* 17 */ { hufftab16, 2, 4 }, + /* 18 */ { hufftab16, 3, 4 }, + /* 19 */ { hufftab16, 4, 4 }, + /* 20 */ { hufftab16, 6, 4 }, + /* 21 */ { hufftab16, 8, 4 }, + /* 22 */ { hufftab16, 10, 4 }, + /* 23 */ { hufftab16, 13, 4 }, + /* 24 */ { hufftab24, 4, 4 }, + /* 25 */ { hufftab24, 5, 4 }, + /* 26 */ { hufftab24, 6, 4 }, + /* 27 */ { hufftab24, 7, 4 }, + /* 28 */ { hufftab24, 8, 4 }, + /* 29 */ { hufftab24, 9, 4 }, + /* 30 */ { hufftab24, 11, 4 }, + /* 31 */ { hufftab24, 13, 4 } +}; diff --git a/core/multimedia/opieplayer/libmad/huffman.h b/core/multimedia/opieplayer/libmad/huffman.h new file mode 100644 index 0000000..1801210 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/huffman.h @@ -0,0 +1,66 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_HUFFMAN_H +# define LIBMAD_HUFFMAN_H + +union huffquad { + struct { + unsigned short final : 1; + unsigned short hlen : 3; + unsigned short v : 1; + unsigned short w : 1; + unsigned short x : 1; + unsigned short y : 1; + } value; + struct { + unsigned short final : 1; + unsigned short bits : 3; + unsigned short offset : 12; + } ptr; + unsigned short final : 1; +}; + +union huffpair { + struct { + unsigned short final : 1; + unsigned short hlen : 3; + unsigned short x : 4; + unsigned short y : 4; + } value; + struct { + unsigned short final : 1; + unsigned short bits : 3; + unsigned short offset : 12; + } ptr; + unsigned short final : 1; +}; + +struct hufftable { + union huffpair const *table; + unsigned short linbits; + unsigned short startbits; +}; + +extern union huffquad const *const mad_huff_quad_table[2]; +extern struct hufftable const mad_huff_pair_table[32]; + +# endif diff --git a/core/multimedia/opieplayer/libmad/imdct_l_arm.S b/core/multimedia/opieplayer/libmad/imdct_l_arm.S new file mode 100644 index 0000000..b86ba11 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/imdct_l_arm.S @@ -0,0 +1,1000 @@ +/***************************************************************************** +* Copyright (C) 2000-2001 Andre McCurdy +* +* This program is free software. you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation@ either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY, without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program@ if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +***************************************************************************** +* +* Notes: +* +* +***************************************************************************** +* +* $Id$ +* +* 2001/03/24: Andre McCurdy +* - Corrected PIC unsafe loading of address of 'imdct36_long_karray' +* +* 2000/09/20: Robert Leslie +* - Added a global symbol with leading underscore per suggestion of +* Simon Burge to support linking with the a.out format. +* +* 2000/09/15: Robert Leslie +* - Fixed a small bug where flags were changed before a conditional branch. +* +* 2000/09/15: Andre McCurdy +* - Applied Nicolas Pitre's rounding optimisation in all remaining places. +* +* 2000/09/09: Nicolas Pitre +* - Optimized rounding + scaling operations. +* +* 2000/08/09: Andre McCurdy +* - Original created. +* +****************************************************************************/ + + +/* + On entry: + + r0 = pointer to 18 element input array + r1 = pointer to 36 element output array + r2 = windowing block type + + + Stack frame created during execution of the function: + + Initial Holds: + Stack + pointer + minus: + + 0 + 4 lr + 8 r11 + 12 r10 + 16 r9 + 20 r8 + 24 r7 + 28 r6 + 32 r5 + 36 r4 + + 40 r2 : windowing block type + + 44 ct00 high + 48 ct00 low + 52 ct01 high + 56 ct01 low + 60 ct04 high + 64 ct04 low + 68 ct06 high + 72 ct06 low + 76 ct05 high + 80 ct05 low + 84 ct03 high + 88 ct03 low + 92 -ct05 high + 96 -ct05 low + 100 -ct07 high + 104 -ct07 low + 108 ct07 high + 112 ct07 low + 116 ct02 high + 120 ct02 low +*/ + +#define BLOCK_MODE_NORMAL 0 +#define BLOCK_MODE_START 1 +#define BLOCK_MODE_STOP 3 + + +#define X0 0x00 +#define X1 0x04 +#define X2 0x08 +#define X3 0x0C +#define X4 0x10 +#define X5 0x14 +#define X6 0x18 +#define X7 0x1c +#define X8 0x20 +#define X9 0x24 +#define X10 0x28 +#define X11 0x2c +#define X12 0x30 +#define X13 0x34 +#define X14 0x38 +#define X15 0x3c +#define X16 0x40 +#define X17 0x44 + +#define x0 0x00 +#define x1 0x04 +#define x2 0x08 +#define x3 0x0C +#define x4 0x10 +#define x5 0x14 +#define x6 0x18 +#define x7 0x1c +#define x8 0x20 +#define x9 0x24 +#define x10 0x28 +#define x11 0x2c +#define x12 0x30 +#define x13 0x34 +#define x14 0x38 +#define x15 0x3c +#define x16 0x40 +#define x17 0x44 +#define x18 0x48 +#define x19 0x4c +#define x20 0x50 +#define x21 0x54 +#define x22 0x58 +#define x23 0x5c +#define x24 0x60 +#define x25 0x64 +#define x26 0x68 +#define x27 0x6c +#define x28 0x70 +#define x29 0x74 +#define x30 0x78 +#define x31 0x7c +#define x32 0x80 +#define x33 0x84 +#define x34 0x88 +#define x35 0x8c + +#define K00 0x0ffc19fd +#define K01 0x00b2aa3e +#define K02 0x0fdcf549 +#define K03 0x0216a2a2 +#define K04 0x0f9ee890 +#define K05 0x03768962 +#define K06 0x0f426cb5 +#define K07 0x04cfb0e2 +#define K08 0x0ec835e8 +#define K09 0x061f78aa +#define K10 0x0e313245 +#define K11 0x07635284 +#define K12 0x0d7e8807 +#define K13 0x0898c779 +#define K14 0x0cb19346 +#define K15 0x09bd7ca0 +#define K16 0x0bcbe352 +#define K17 0x0acf37ad + +#define minus_K02 0xf0230ab7 + +#define WL0 0x00b2aa3e +#define WL1 0x0216a2a2 +#define WL2 0x03768962 +#define WL3 0x04cfb0e2 +#define WL4 0x061f78aa +#define WL5 0x07635284 +#define WL6 0x0898c779 +#define WL7 0x09bd7ca0 +#define WL8 0x0acf37ad +#define WL9 0x0bcbe352 +#define WL10 0x0cb19346 +#define WL11 0x0d7e8807 +#define WL12 0x0e313245 +#define WL13 0x0ec835e8 +#define WL14 0x0f426cb5 +#define WL15 0x0f9ee890 +#define WL16 0x0fdcf549 +#define WL17 0x0ffc19fd + + +@***************************************************************************** + + + .text + .align + + .global III_imdct_l + .global _III_imdct_l + +III_imdct_l: +_III_imdct_l: + + stmdb sp!, { r2, r4 - r11, lr } @ all callee saved regs, plus arg3 + + ldr r4, =K08 @ r4 = K08 + ldr r5, =K09 @ r5 = K09 + ldr r8, [r0, #X4] @ r8 = X4 + ldr r9, [r0, #X13] @ r9 = X13 + rsb r6, r4, #0 @ r6 = -K08 + rsb r7, r5, #0 @ r7 = -K09 + + smull r2, r3, r4, r8 @ r2..r3 = (X4 * K08) + smlal r2, r3, r5, r9 @ r2..r3 = (X4 * K08) + (X13 * K09) = ct01 + + smull r10, lr, r8, r5 @ r10..lr = (X4 * K09) + smlal r10, lr, r9, r6 @ r10..lr = (X4 * K09) + (X13 * -K08) = ct00 + + ldr r8, [r0, #X7] @ r8 = X7 + ldr r9, [r0, #X16] @ r9 = X16 + + stmdb sp!, { r2, r3, r10, lr } @ stack ct00_h, ct00_l, ct01_h, ct01_l + + add r8, r8, r9 @ r8 = (X7 + X16) + ldr r9, [r0, #X1] @ r9 = X1 + + smlal r2, r3, r6, r8 @ r2..r3 = ct01 + ((X7 + X16) * -K08) + smlal r2, r3, r7, r9 @ r2..r3 += (X1 * -K09) + + ldr r7, [r0, #X10] @ r7 = X10 + + rsbs r10, r10, #0 + rsc lr, lr, #0 @ r10..lr = -ct00 + + smlal r2, r3, r5, r7 @ r2..r3 += (X10 * K09) = ct06 + + smlal r10, lr, r9, r6 @ r10..lr = -ct00 + ( X1 * -K08) + smlal r10, lr, r8, r5 @ r10..lr += ((X7 + X16) * K09) + smlal r10, lr, r7, r4 @ r10..lr += ( X10 * K08) = ct04 + + stmdb sp!, { r2, r3, r10, lr } @ stack ct04_h, ct04_l, ct06_h, ct06_l + + @---- + + ldr r7, [r0, #X0] + ldr r8, [r0, #X11] + ldr r9, [r0, #X12] + sub r7, r7, r8 + sub r7, r7, r9 @ r7 = (X0 - X11 -X12) = ct14 + + ldr r9, [r0, #X3] + ldr r8, [r0, #X8] + ldr r11, [r0, #X15] + sub r8, r8, r9 + add r8, r8, r11 @ r8 = (X8 - X3 + X15) = ct16 + + add r11, r7, r8 @ r11 = ct14 + ct16 = ct18 + + smlal r2, r3, r6, r11 @ r2..r3 = ct06 + ((X0 - X11 - X3 + X15 + X8 - X12) * -K08) + + ldr r6, [r0, #X2] + ldr r9, [r0, #X9] + ldr r12, [r0, #X14] + sub r6, r6, r9 + sub r6, r6, r12 @ r6 = (X2 - X9 - X14) = ct15 + + ldr r9, [r0, #X5] + ldr r12, [r0, #X6] + sub r9, r9, r12 + ldr r12, [r0, #X17] + sub r9, r9, r12 @ r9 = (X5 - X6 - X17) = ct17 + + add r12, r9, r6 @ r12 = ct15 + ct17 = ct19 + + smlal r2, r3, r5, r12 @ r2..r3 += ((X2 - X9 + X5 - X6 - X17 - X14) * K09) + + smlal r10, lr, r11, r5 @ r10..lr = ct04 + (ct18 * K09) + smlal r10, lr, r12, r4 @ r10..lr = ct04 + (ct18 * K09) + (ct19 * K08) + + movs r2, r2, lsr #28 + adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3 + str r2, [r1, #x22] @ store result x22 + + movs r10, r10, lsr #28 + adc r10, r10, lr, lsl #4 @ r10 = bits[59..28] of r10..lr + str r10, [r1, #x4] @ store result x4 + + @---- + + ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp) + + @ r2..r3 = ct06 + @ r4..r5 = ct04 + @ r6 = ct15 + @ r7 = ct14 + @ r8 = ct16 + @ r9 = ct17 + @ r10 = . + @ r11 = . + @ r12 = . + @ lr = . + + ldr r10, =K03 @ r10 = K03 + ldr lr, =K15 @ lr = K15 + + smlal r2, r3, r10, r7 @ r2..r3 = ct06 + (ct14 * K03) + smlal r4, r5, lr, r7 @ r4..r5 = ct04 + (ct14 * K15) + + ldr r12, =K14 @ r12 = K14 + rsb r10, r10, #0 @ r10 = -K03 + + smlal r2, r3, lr, r6 @ r2..r3 += (ct15 * K15) + smlal r4, r5, r10, r6 @ r4..r5 += (ct15 * -K03) + smlal r2, r3, r12, r8 @ r2..r3 += (ct16 * K14) + + ldr r11, =minus_K02 @ r11 = -K02 + rsb r12, r12, #0 @ r12 = -K14 + + smlal r4, r5, r12, r9 @ r4..r5 += (ct17 * -K14) + smlal r2, r3, r11, r9 @ r2..r3 += (ct17 * -K02) + smlal r4, r5, r11, r8 @ r4..r5 += (ct16 * -K02) + + movs r2, r2, lsr #28 + adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3 + str r2, [r1, #x7] @ store result x7 + + movs r4, r4, lsr #28 + adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5 + str r4, [r1, #x1] @ store result x1 + + @---- + + ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp) + + @ r2..r3 = ct06 + @ r4..r5 = ct04 + @ r6 = ct15 + @ r7 = ct14 + @ r8 = ct16 + @ r9 = ct17 + @ r10 = -K03 + @ r11 = -K02 + @ r12 = -K14 + @ lr = K15 + + rsbs r2, r2, #0 + rsc r3, r3, #0 @ r2..r3 = -ct06 + + smlal r2, r3, r12, r7 @ r2..r3 = -ct06 + (ct14 * -K14) + smlal r2, r3, r10, r8 @ r2..r3 += (ct16 * -K03) + + smlal r4, r5, r12, r6 @ r4..r5 = ct04 + (ct15 * -K14) + smlal r4, r5, r10, r9 @ r4..r5 += (ct17 * -K03) + smlal r4, r5, lr, r8 @ r4..r5 += (ct16 * K15) + smlal r4, r5, r11, r7 @ r4..r5 += (ct14 * -K02) + + rsb lr, lr, #0 @ lr = -K15 + rsb r11, r11, #0 @ r11 = K02 + + smlal r2, r3, lr, r9 @ r2..r3 += (ct17 * -K15) + smlal r2, r3, r11, r6 @ r2..r3 += (ct15 * K02) + + movs r4, r4, lsr #28 + adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5 + str r4, [r1, #x25] @ store result x25 + + movs r2, r2, lsr #28 + adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3 + str r2, [r1, #x19] @ store result x19 + + @---- + + ldr r2, [sp, #16] @ r2 = ct01_l + ldr r3, [sp, #20] @ r3 = ct01_h + + ldr r6, [r0, #X1] + ldr r8, [r0, #X7] + ldr r9, [r0, #X10] + ldr r7, [r0, #X16] + + rsbs r2, r2, #0 + rsc r3, r3, #0 @ r2..r3 = -ct01 + + mov r4, r2 + mov r5, r3 @ r4..r5 = -ct01 + + @ r2..r3 = -ct01 + @ r4..r5 = -ct01 + @ r6 = X1 + @ r7 = X16 + @ r8 = X7 + @ r9 = X10 + @ r10 = -K03 + @ r11 = K02 + @ r12 = -K14 + @ lr = -K15 + + smlal r4, r5, r12, r7 @ r4..r5 = -ct01 + (X16 * -K14) + smlal r2, r3, lr, r9 @ r2..r3 = -ct01 + (X10 * -K15) + + smlal r4, r5, r10, r8 @ r4..r5 += (X7 * -K03) + smlal r2, r3, r10, r7 @ r2..r3 += (X16 * -K03) + + smlal r4, r5, r11, r9 @ r4..r5 += (X10 * K02) + smlal r2, r3, r12, r8 @ r2..r3 += (X7 * -K14) + + rsb lr, lr, #0 @ lr = K15 + rsb r11, r11, #0 @ r11 = -K02 + + smlal r4, r5, lr, r6 @ r4..r5 += (X1 * K15) = ct05 + smlal r2, r3, r11, r6 @ r2..r3 += (X1 * -K02) = ct03 + + stmdb sp!, { r2, r3, r4, r5 } @ stack ct05_h, ct05_l, ct03_h, ct03_l + + rsbs r4, r4, #0 + rsc r5, r5, #0 @ r4..r5 = -ct05 + + stmdb sp!, { r4, r5 } @ stack -ct05_h, -ct05_l + + ldr r2, [sp, #48] @ r2 = ct00_l + ldr r3, [sp, #52] @ r3 = ct00_h + + rsb r10, r10, #0 @ r10 = K03 + + rsbs r4, r2, #0 + rsc r5, r3, #0 @ r4..r5 = -ct00 + + @ r2..r3 = ct00 + @ r4..r5 = -ct00 + @ r6 = X1 + @ r7 = X16 + @ r8 = X7 + @ r9 = X10 + @ r10 = K03 + @ r11 = -K02 + @ r12 = -K14 + @ lr = K15 + + smlal r4, r5, r10, r6 @ r4..r5 = -ct00 + (X1 * K03) + smlal r2, r3, r10, r9 @ r2..r3 = ct00 + (X10 * K03) + + smlal r4, r5, r12, r9 @ r4..r5 += (X10 * -K14) + smlal r2, r3, r12, r6 @ r2..r3 += (X1 * -K14) + + smlal r4, r5, r11, r7 @ r4..r5 += (X16 * -K02) + smlal r4, r5, lr, r8 @ r4..r5 += (X7 * K15) = ct07 + + rsb lr, lr, #0 @ lr = -K15 + rsb r11, r11, #0 @ r11 = K02 + + smlal r2, r3, r11, r8 @ r2..r3 += (X7 * K02) + smlal r2, r3, lr, r7 @ r2..r3 += (X16 * -K15) = ct02 + + rsbs r6, r4, #0 + rsc r7, r5, #0 @ r6..r7 = -ct07 + + stmdb sp!, { r2 - r7 } @ stack -ct07_h, -ct07_l, ct07_h, ct07_l, ct02_h, ct02_l + + + @---- + + add r2, pc, #(imdct36_long_karray-.-8) @ r2 = base address of Knn array (PIC safe ?) + + +loop: + ldr r12, [r0, #X0] + + ldmia r2!, { r5 - r11 } @ first 7 words from Karray element + + smull r3, r4, r5, r12 @ sum = (Kxx * X0) + ldr r12, [r0, #X2] + ldr r5, [r0, #X3] + smlal r3, r4, r6, r12 @ sum += (Kxx * X2) + ldr r12, [r0, #X5] + ldr r6, [r0, #X6] + smlal r3, r4, r7, r5 @ sum += (Kxx * X3) + smlal r3, r4, r8, r12 @ sum += (Kxx * X5) + ldr r12, [r0, #X8] + ldr r5, [r0, #X9] + smlal r3, r4, r9, r6 @ sum += (Kxx * X6) + smlal r3, r4, r10, r12 @ sum += (Kxx * X8) + smlal r3, r4, r11, r5 @ sum += (Kxx * X9) + + ldmia r2!, { r5 - r10 } @ final 6 words from Karray element + + ldr r11, [r0, #X11] + ldr r12, [r0, #X12] + smlal r3, r4, r5, r11 @ sum += (Kxx * X11) + ldr r11, [r0, #X14] + ldr r5, [r0, #X15] + smlal r3, r4, r6, r12 @ sum += (Kxx * X12) + smlal r3, r4, r7, r11 @ sum += (Kxx * X14) + ldr r11, [r0, #X17] + smlal r3, r4, r8, r5 @ sum += (Kxx * X15) + smlal r3, r4, r9, r11 @ sum += (Kxx * X17) + + add r5, sp, r10, lsr #16 @ create index back into stack for required ctxx + + ldmia r5, { r6, r7 } @ r6..r7 = ctxx + + mov r8, r10, lsl #16 @ push ctxx index off the top end + + adds r3, r3, r6 @ add low words + adc r4, r4, r7 @ add high words, with carry + movs r3, r3, lsr #28 + adc r3, r3, r4, lsl #4 @ r3 = bits[59..28] of r3..r4 + + str r3, [r1, r8, lsr #24] @ push completion flag off the bottom end + + movs r8, r8, lsl #8 @ push result location index off the top end + beq loop @ loop back if completion flag not set + b imdct_l_windowing @ branch to windowing stage if looping finished + +imdct36_long_karray: + + .word K17, -K13, K10, -K06, -K05, K01, -K00, K04, -K07, K11, K12, -K16, 0x00000000 + .word K13, K07, K16, K01, K10, -K05, K04, -K11, K00, -K17, K06, -K12, 0x00200800 + .word K11, K17, K05, K12, -K01, K06, -K07, K00, -K13, K04, -K16, K10, 0x00200c00 + .word K07, K00, -K12, K05, -K16, -K10, K11, -K17, K04, K13, K01, K06, 0x00001400 + .word K05, K10, -K00, -K17, K07, -K13, K12, K06, -K16, K01, -K11, -K04, 0x00181800 + .word K01, K05, -K07, -K11, K13, K17, -K16, -K12, K10, K06, -K04, -K00, 0x00102000 + .word -K16, K12, -K11, K07, K04, -K00, -K01, K05, -K06, K10, K13, -K17, 0x00284800 + .word -K12, K06, K17, -K00, -K11, K04, K05, -K10, K01, K16, -K07, -K13, 0x00085000 + .word -K10, K16, K04, -K13, -K00, K07, K06, -K01, -K12, -K05, K17, K11, 0x00105400 + .word -K06, -K01, K13, K04, K17, -K11, -K10, -K16, -K05, K12, K00, K07, 0x00185c00 + .word -K04, -K11, -K01, K16, K06, K12, K13, -K07, -K17, -K00, -K10, -K05, 0x00006000 + .word -K00, -K04, -K06, -K10, -K12, -K16, -K17, -K13, -K11, -K07, -K05, -K01, 0x00206801 + + + @---- + @------------------------------------------------------------------------- + @---- + +imdct_l_windowing: + + ldr r11, [sp, #80] @ fetch function parameter 3 from out of the stack + ldmia r1!, { r0, r2 - r9 } @ load 9 words from x0, update pointer + + @ r0 = x0 + @ r1 = &x[9] + @ r2 = x1 + @ r3 = x2 + @ r4 = x3 + @ r5 = x4 + @ r6 = x5 + @ r7 = x6 + @ r8 = x7 + @ r9 = x8 + @ r10 = . + @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block) + @ r12 = . + @ lr = . + + cmp r11, #BLOCK_MODE_STOP @ setup flags + rsb r10, r0, #0 @ r10 = -x0 (DONT change flags !!) + beq stop_block_x0_to_x17 + + + @ start and normal blocks are treated the same for x[0]..x[17] + +normal_block_x0_to_x17: + + ldr r12, =WL9 @ r12 = window_l[9] + + rsb r0, r9, #0 @ r0 = -x8 + rsb r9, r2, #0 @ r9 = -x1 + rsb r2, r8, #0 @ r2 = -x7 + rsb r8, r3, #0 @ r8 = -x2 + rsb r3, r7, #0 @ r3 = -x6 + rsb r7, r4, #0 @ r7 = -x3 + rsb r4, r6, #0 @ r4 = -x5 + rsb r6, r5, #0 @ r6 = -x4 + + @ r0 = -x8 + @ r1 = &x[9] + @ r2 = -x7 + @ r3 = -x6 + @ r4 = -x5 + @ r5 = . + @ r6 = -x4 + @ r7 = -x3 + @ r8 = -x2 + @ r9 = -x1 + @ r10 = -x0 + @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block) + @ r12 = window_l[9] + @ lr = . + + smull r5, lr, r12, r0 @ r5..lr = (window_l[9] * (x[9] == -x[8])) + ldr r12, =WL10 @ r12 = window_l[10] + movs r5, r5, lsr #28 + adc r0, r5, lr, lsl #4 @ r0 = bits[59..28] of windowed x9 + + smull r5, lr, r12, r2 @ r5..lr = (window_l[10] * (x[10] == -x[7])) + ldr r12, =WL11 @ r12 = window_l[11] + movs r5, r5, lsr #28 + adc r2, r5, lr, lsl #4 @ r2 = bits[59..28] of windowed x10 + + smull r5, lr, r12, r3 @ r5..lr = (window_l[11] * (x[11] == -x[6])) + ldr r12, =WL12 @ r12 = window_l[12] + movs r5, r5, lsr #28 + adc r3, r5, lr, lsl #4 @ r3 = bits[59..28] of windowed x11 + + smull r5, lr, r12, r4 @ r5..lr = (window_l[12] * (x[12] == -x[5])) + ldr r12, =WL13 @ r12 = window_l[13] + movs r5, r5, lsr #28 + adc r4, r5, lr, lsl #4 @ r4 = bits[59..28] of windowed x12 + + smull r5, lr, r12, r6 @ r5..lr = (window_l[13] * (x[13] == -x[4])) + ldr r12, =WL14 @ r12 = window_l[14] + movs r5, r5, lsr #28 + adc r6, r5, lr, lsl #4 @ r6 = bits[59..28] of windowed x13 + + smull r5, lr, r12, r7 @ r5..lr = (window_l[14] * (x[14] == -x[3])) + ldr r12, =WL15 @ r12 = window_l[15] + movs r5, r5, lsr #28 + adc r7, r5, lr, lsl #4 @ r7 = bits[59..28] of windowed x14 + + smull r5, lr, r12, r8 @ r5..lr = (window_l[15] * (x[15] == -x[2])) + ldr r12, =WL16 @ r12 = window_l[16] + movs r5, r5, lsr #28 + adc r8, r5, lr, lsl #4 @ r8 = bits[59..28] of windowed x15 + + smull r5, lr, r12, r9 @ r5..lr = (window_l[16] * (x[16] == -x[1])) + ldr r12, =WL17 @ r12 = window_l[17] + movs r5, r5, lsr #28 + adc r9, r5, lr, lsl #4 @ r9 = bits[59..28] of windowed x16 + + smull r5, lr, r12, r10 @ r5..lr = (window_l[17] * (x[17] == -x[0])) + ldr r12, =WL0 @ r12 = window_l[0] + movs r5, r5, lsr #28 + adc r10, r5, lr, lsl #4 @ r10 = bits[59..28] of windowed x17 + + + stmia r1, { r0, r2 - r4, r6 - r10 } @ store windowed x[9] .. x[17] + ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x0 + + + smull r10, lr, r12, r0 @ r10..lr = (window_l[0] * x[0]) + ldr r12, =WL1 @ r12 = window_l[1] + movs r10, r10, lsr #28 + adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0 + + smull r10, lr, r12, r2 @ r10..lr = (window_l[1] * x[1]) + ldr r12, =WL2 @ r12 = window_l[2] + movs r10, r10, lsr #28 + adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1 + + smull r10, lr, r12, r3 @ r10..lr = (window_l[2] * x[2]) + ldr r12, =WL3 @ r12 = window_l[3] + movs r10, r10, lsr #28 + adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2 + + smull r10, lr, r12, r4 @ r10..lr = (window_l[3] * x[3]) + ldr r12, =WL4 @ r12 = window_l[4] + movs r10, r10, lsr #28 + adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3 + + smull r10, lr, r12, r5 @ r10..lr = (window_l[4] * x[4]) + ldr r12, =WL5 @ r12 = window_l[5] + movs r10, r10, lsr #28 + adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4 + + smull r10, lr, r12, r6 @ r10..lr = (window_l[5] * x[5]) + ldr r12, =WL6 @ r12 = window_l[6] + movs r10, r10, lsr #28 + adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5 + + smull r10, lr, r12, r7 @ r10..lr = (window_l[6] * x[6]) + ldr r12, =WL7 @ r12 = window_l[7] + movs r10, r10, lsr #28 + adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6 + + smull r10, lr, r12, r8 @ r10..lr = (window_l[7] * x[7]) + ldr r12, =WL8 @ r12 = window_l[8] + movs r10, r10, lsr #28 + adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7 + + smull r10, lr, r12, r9 @ r10..lr = (window_l[8] * x[8]) + movs r10, r10, lsr #28 + adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8 + + stmia r1, { r0, r2 - r9 } @ store windowed x[0] .. x[8] + + cmp r11, #BLOCK_MODE_START + beq start_block_x18_to_x35 + + + @---- + + +normal_block_x18_to_x35: + + ldr r11, =WL3 @ r11 = window_l[3] + ldr r12, =WL4 @ r12 = window_l[4] + + add r1, r1, #(18*4) @ r1 = &x[18] + + ldmia r1!, { r0, r2 - r4, r6 - r10 } @ load 9 words from x18, update pointer + + @ r0 = x18 + @ r1 = &x[27] + @ r2 = x19 + @ r3 = x20 + @ r4 = x21 + @ r5 = . + @ r6 = x22 + @ r7 = x23 + @ r8 = x24 + @ r9 = x25 + @ r10 = x26 + @ r11 = window_l[3] + @ r12 = window_l[4] + @ lr = . + + smull r5, lr, r12, r6 @ r5..lr = (window_l[4] * (x[22] == x[31])) + movs r5, r5, lsr #28 + adc r5, r5, lr, lsl #4 @ r5 = bits[59..28] of windowed x31 + + smull r6, lr, r11, r4 @ r5..lr = (window_l[3] * (x[21] == x[32])) + ldr r12, =WL5 @ r12 = window_l[5] + movs r6, r6, lsr #28 + adc r6, r6, lr, lsl #4 @ r6 = bits[59..28] of windowed x32 + + smull r4, lr, r12, r7 @ r4..lr = (window_l[5] * (x[23] == x[30])) + ldr r11, =WL1 @ r11 = window_l[1] + ldr r12, =WL2 @ r12 = window_l[2] + movs r4, r4, lsr #28 + adc r4, r4, lr, lsl #4 @ r4 = bits[59..28] of windowed x30 + + smull r7, lr, r12, r3 @ r7..lr = (window_l[2] * (x[20] == x[33])) + ldr r12, =WL6 @ r12 = window_l[6] + movs r7, r7, lsr #28 + adc r7, r7, lr, lsl #4 @ r7 = bits[59..28] of windowed x33 + + smull r3, lr, r12, r8 @ r3..lr = (window_l[6] * (x[24] == x[29])) + movs r3, r3, lsr #28 + adc r3, r3, lr, lsl #4 @ r3 = bits[59..28] of windowed x29 + + smull r8, lr, r11, r2 @ r7..lr = (window_l[1] * (x[19] == x[34])) + ldr r12, =WL7 @ r12 = window_l[7] + ldr r11, =WL8 @ r11 = window_l[8] + movs r8, r8, lsr #28 + adc r8, r8, lr, lsl #4 @ r8 = bits[59..28] of windowed x34 + + smull r2, lr, r12, r9 @ r7..lr = (window_l[7] * (x[25] == x[28])) + ldr r12, =WL0 @ r12 = window_l[0] + movs r2, r2, lsr #28 + adc r2, r2, lr, lsl #4 @ r2 = bits[59..28] of windowed x28 + + smull r9, lr, r12, r0 @ r3..lr = (window_l[0] * (x[18] == x[35])) + movs r9, r9, lsr #28 + adc r9, r9, lr, lsl #4 @ r9 = bits[59..28] of windowed x35 + + smull r0, lr, r11, r10 @ r7..lr = (window_l[8] * (x[26] == x[27])) + ldr r11, =WL16 @ r11 = window_l[16] + ldr r12, =WL17 @ r12 = window_l[17] + movs r0, r0, lsr #28 + adc r0, r0, lr, lsl #4 @ r0 = bits[59..28] of windowed x27 + + + stmia r1, { r0, r2 - r9 } @ store windowed x[27] .. x[35] + ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x18 + + + smull r10, lr, r12, r0 @ r10..lr = (window_l[17] * x[18]) + movs r10, r10, lsr #28 + adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0 + + smull r10, lr, r11, r2 @ r10..lr = (window_l[16] * x[19]) + ldr r11, =WL14 @ r11 = window_l[14] + ldr r12, =WL15 @ r12 = window_l[15] + movs r10, r10, lsr #28 + adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1 + + smull r10, lr, r12, r3 @ r10..lr = (window_l[15] * x[20]) + movs r10, r10, lsr #28 + adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2 + + smull r10, lr, r11, r4 @ r10..lr = (window_l[14] * x[21]) + ldr r11, =WL12 @ r11 = window_l[12] + ldr r12, =WL13 @ r12 = window_l[13] + movs r10, r10, lsr #28 + adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3 + + smull r10, lr, r12, r5 @ r10..lr = (window_l[13] * x[22]) + movs r10, r10, lsr #28 + adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4 + + smull r10, lr, r11, r6 @ r10..lr = (window_l[12] * x[23]) + ldr r11, =WL10 @ r12 = window_l[10] + ldr r12, =WL11 @ r12 = window_l[11] + movs r10, r10, lsr #28 + adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5 + + smull r10, lr, r12, r7 @ r10..lr = (window_l[11] * x[24]) + movs r10, r10, lsr #28 + adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6 + + smull r10, lr, r11, r8 @ r10..lr = (window_l[10] * x[25]) + ldr r12, =WL9 @ r12 = window_l[9] + movs r10, r10, lsr #28 + adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7 + + smull r10, lr, r12, r9 @ r10..lr = (window_l[9] * x[26]) + + movs r10, r10, lsr #28 + adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8 + + stmia r1, { r0, r2 - r9 } @ store windowed x[18] .. x[26] + + @---- + @ NB there are 2 possible exits from this function - this is only one of them + @---- + + add sp, sp, #(21*4) @ return stack frame + ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return + + @---- + + +stop_block_x0_to_x17: + + @ r0 = x0 + @ r1 = &x[9] + @ r2 = x1 + @ r3 = x2 + @ r4 = x3 + @ r5 = x4 + @ r6 = x5 + @ r7 = x6 + @ r8 = x7 + @ r9 = x8 + @ r10 = -x0 + @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block) + @ r12 = . + @ lr = . + + rsb r0, r6, #0 @ r0 = -x5 + rsb r6, r2, #0 @ r6 = -x1 + rsb r2, r5, #0 @ r2 = -x4 + rsb r5, r3, #0 @ r5 = -x2 + rsb r3, r4, #0 @ r3 = -x3 + + add r1, r1, #(3*4) @ r1 = &x[12] + stmia r1, { r0, r2, r3, r5, r6, r10 } @ store unchanged x[12] .. x[17] + + ldr r0, =WL1 @ r0 = window_l[1] == window_s[0] + + rsb r10, r9, #0 @ r10 = -x8 + rsb r12, r8, #0 @ r12 = -x7 + rsb lr, r7, #0 @ lr = -x6 + + @ r0 = WL1 + @ r1 = &x[12] + @ r2 = . + @ r3 = . + @ r4 = . + @ r5 = . + @ r6 = . + @ r7 = x6 + @ r8 = x7 + @ r9 = x8 + @ r10 = -x8 + @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block) + @ r12 = -x7 + @ lr = -x6 + + smull r5, r6, r0, r7 @ r5..r6 = (window_l[1] * x[6]) + ldr r2, =WL4 @ r2 = window_l[4] == window_s[1] + movs r5, r5, lsr #28 + adc r7, r5, r6, lsl #4 @ r7 = bits[59..28] of windowed x6 + + smull r5, r6, r2, r8 @ r5..r6 = (window_l[4] * x[7]) + ldr r3, =WL7 @ r3 = window_l[7] == window_s[2] + movs r5, r5, lsr #28 + adc r8, r5, r6, lsl #4 @ r8 = bits[59..28] of windowed x7 + + smull r5, r6, r3, r9 @ r5..r6 = (window_l[7] * x[8]) + ldr r4, =WL10 @ r4 = window_l[10] == window_s[3] + movs r5, r5, lsr #28 + adc r9, r5, r6, lsl #4 @ r9 = bits[59..28] of windowed x8 + + smull r5, r6, r4, r10 @ r5..r6 = (window_l[10] * (x[9] == -x[8])) + ldr r0, =WL13 @ r0 = window_l[13] == window_s[4] + movs r5, r5, lsr #28 + adc r10, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9 + + smull r5, r6, r0, r12 @ r5..r6 = (window_l[13] * (x[10] == -x[7])) + ldr r2, =WL16 @ r2 = window_l[16] == window_s[5] + movs r5, r5, lsr #28 + adc r12, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9 + + smull r5, r6, r2, lr @ r5..r6 = (window_l[16] * (x[11] == -x[6])) + + ldr r0, =0x00 + + movs r5, r5, lsr #28 + adc lr, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9 + + stmdb r1!, { r7 - r10, r12, lr } @ store windowed x[6] .. x[11] + + ldr r5, =0x00 + ldr r6, =0x00 + ldr r2, =0x00 + ldr r3, =0x00 + ldr r4, =0x00 + + stmdb r1!, { r0, r2 - r6 } @ store windowed x[0] .. x[5] + + b normal_block_x18_to_x35 + + + @---- + + +start_block_x18_to_x35: + + ldr r4, =WL1 @ r0 = window_l[1] == window_s[0] + + add r1, r1, #(24*4) @ r1 = &x[24] + + ldmia r1, { r0, r2, r3 } @ load 3 words from x24, dont update pointer + + @ r0 = x24 + @ r1 = &x[24] + @ r2 = x25 + @ r3 = x26 + @ r4 = WL1 + @ r5 = WL4 + @ r6 = WL7 + @ r7 = WL10 + @ r8 = WL13 + @ r9 = WL16 + @ r10 = . + @ r11 = . + @ r12 = . + @ lr = . + + ldr r5, =WL4 @ r5 = window_l[4] == window_s[1] + + smull r10, r11, r4, r0 @ r10..r11 = (window_l[1] * (x[24] == x[29])) + ldr r6, =WL7 @ r6 = window_l[7] == window_s[2] + movs r10, r10, lsr #28 + adc lr, r10, r11, lsl #4 @ lr = bits[59..28] of windowed x29 + + smull r10, r11, r5, r2 @ r10..r11 = (window_l[4] * (x[25] == x[28])) + ldr r7, =WL10 @ r7 = window_l[10] == window_s[3] + movs r10, r10, lsr #28 + adc r12, r10, r11, lsl #4 @ r12 = bits[59..28] of windowed x28 + + smull r10, r11, r6, r3 @ r10..r11 = (window_l[7] * (x[26] == x[27])) + ldr r8, =WL13 @ r8 = window_l[13] == window_s[4] + movs r10, r10, lsr #28 + adc r4, r10, r11, lsl #4 @ r4 = bits[59..28] of windowed x27 + + smull r10, r11, r7, r3 @ r10..r11 = (window_l[10] * x[26]) + ldr r9, =WL16 @ r9 = window_l[16] == window_s[5] + movs r10, r10, lsr #28 + adc r3, r10, r11, lsl #4 @ r3 = bits[59..28] of windowed x26 + + smull r10, r11, r8, r2 @ r10..r11 = (window_l[13] * x[25]) + ldr r5, =0x00 + movs r10, r10, lsr #28 + adc r2, r10, r11, lsl #4 @ r2 = bits[59..28] of windowed x25 + + smull r10, r11, r9, r0 @ r10..r11 = (window_l[16] * x[24]) + ldr r6, =0x00 + movs r10, r10, lsr #28 + adc r0, r10, r11, lsl #4 @ r0 = bits[59..28] of windowed x24 + + stmia r1!, { r0, r2, r3, r4, r12, lr } @ store windowed x[24] .. x[29] + + ldr r7, =0x00 + ldr r8, =0x00 + ldr r9, =0x00 + ldr r10, =0x00 + + stmia r1!, { r5 - r10 } @ store windowed x[30] .. x[35] + + @---- + @ NB there are 2 possible exits from this function - this is only one of them + @---- + + add sp, sp, #(21*4) @ return stack frame + ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return + + @---- + @END + @---- + diff --git a/core/multimedia/opieplayer/libmad/imdct_s.dat b/core/multimedia/opieplayer/libmad/imdct_s.dat new file mode 100644 index 0000000..00d62eb --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/imdct_s.dat @@ -0,0 +1,62 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + + /* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */, + -MAD_F(0x0ec835e8) /* -0.923879533 */, + -MAD_F(0x0216a2a2) /* -0.130526192 */, + MAD_F(0x0fdcf549) /* 0.991444861 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + -MAD_F(0x0cb19346) /* -0.793353340 */ }, + + /* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */, + MAD_F(0x061f78aa) /* 0.382683432 */, + MAD_F(0x0fdcf549) /* 0.991444861 */, + MAD_F(0x0216a2a2) /* 0.130526192 */, + -MAD_F(0x0ec835e8) /* -0.923879533 */, + -MAD_F(0x09bd7ca0) /* -0.608761429 */ }, + + /* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */, + -MAD_F(0x0ec835e8) /* -0.923879533 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + MAD_F(0x0ec835e8) /* 0.923879533 */ }, + + /* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + MAD_F(0x061f78aa) /* 0.382683432 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, + MAD_F(0x061f78aa) /* 0.382683432 */ }, + + /* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + MAD_F(0x09bd7ca0) /* 0.608761429 */, + -MAD_F(0x0cb19346) /* -0.793353340 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, + -MAD_F(0x0fdcf549) /* -0.991444861 */ }, + + /* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */, + -MAD_F(0x0ec835e8) /* -0.923879533 */, + -MAD_F(0x0cb19346) /* -0.793353340 */, + -MAD_F(0x09bd7ca0) /* -0.608761429 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + -MAD_F(0x0216a2a2) /* -0.130526192 */ } diff --git a/core/multimedia/opieplayer/libmad/layer12.c b/core/multimedia/opieplayer/libmad/layer12.c new file mode 100644 index 0000000..41b17ca --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/layer12.c @@ -0,0 +1,496 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# ifdef HAVE_LIMITS_H +# include +# else +# define CHAR_BIT 8 +# endif + +# include "fixed.h" +# include "bit.h" +# include "stream.h" +# include "frame.h" +# include "layer12.h" + +/* + * scalefactor table + * used in both Layer I and Layer II decoding + */ +static +mad_fixed_t const sf_table[63] = { +# include "sf_table.dat" +}; + +/* --- Layer I ------------------------------------------------------------- */ + +/* linear scaling table */ +static +mad_fixed_t const linear_table[14] = { + MAD_F(0x15555555), /* 2^2 / (2^2 - 1) == 1.33333333333333 */ + MAD_F(0x12492492), /* 2^3 / (2^3 - 1) == 1.14285714285714 */ + MAD_F(0x11111111), /* 2^4 / (2^4 - 1) == 1.06666666666667 */ + MAD_F(0x10842108), /* 2^5 / (2^5 - 1) == 1.03225806451613 */ + MAD_F(0x10410410), /* 2^6 / (2^6 - 1) == 1.01587301587302 */ + MAD_F(0x10204081), /* 2^7 / (2^7 - 1) == 1.00787401574803 */ + MAD_F(0x10101010), /* 2^8 / (2^8 - 1) == 1.00392156862745 */ + MAD_F(0x10080402), /* 2^9 / (2^9 - 1) == 1.00195694716243 */ + MAD_F(0x10040100), /* 2^10 / (2^10 - 1) == 1.00097751710655 */ + MAD_F(0x10020040), /* 2^11 / (2^11 - 1) == 1.00048851978505 */ + MAD_F(0x10010010), /* 2^12 / (2^12 - 1) == 1.00024420024420 */ + MAD_F(0x10008004), /* 2^13 / (2^13 - 1) == 1.00012208521548 */ + MAD_F(0x10004001), /* 2^14 / (2^14 - 1) == 1.00006103888177 */ + MAD_F(0x10002000) /* 2^15 / (2^15 - 1) == 1.00003051850948 */ +}; + +/* + * NAME: I_sample() + * DESCRIPTION: decode one requantized Layer I sample from a bitstream + */ +static +mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb) +{ + mad_fixed_t sample; + + sample = mad_bit_read(ptr, nb); + + /* invert most significant bit, extend sign, then scale to fixed format */ + + sample ^= 1 << (nb - 1); + sample |= -(sample & (1 << (nb - 1))); + + sample <<= MAD_F_FRACBITS - (nb - 1); + + /* requantize the sample */ + + /* s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1)) */ + + sample += MAD_F_ONE >> (nb - 1); + + return mad_f_mul(sample, linear_table[nb - 2]); + + /* s' = factor * s'' */ + /* (to be performed by caller) */ +} + +/* + * NAME: layer->I() + * DESCRIPTION: decode a single Layer I frame + */ +int mad_layer_I(struct mad_stream *stream, struct mad_frame *frame) +{ + struct mad_header *header = &frame->header; + unsigned int nch, bound, ch, s, sb, nb; + unsigned char allocation[2][32], scalefactor[2][32]; + + nch = MAD_NCHANNELS(header); + + bound = 32; + if (header->mode == MAD_MODE_JOINT_STEREO) { + header->flags |= MAD_FLAG_I_STEREO; + bound = 4 + header->mode_extension * 4; + } + + /* check CRC word */ + + if (header->flags & MAD_FLAG_PROTECTION) { + header->crc_check = + mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)), + header->crc_check); + + if (header->crc_check != header->crc_target && + !(frame->options & MAD_OPTION_IGNORECRC)) { + stream->error = MAD_ERROR_BADCRC; + return -1; + } + } + + /* decode bit allocations */ + + for (sb = 0; sb < bound; ++sb) { + for (ch = 0; ch < nch; ++ch) { + nb = mad_bit_read(&stream->ptr, 4); + + if (nb == 15) { + stream->error = MAD_ERROR_BADBITALLOC; + return -1; + } + + allocation[ch][sb] = nb ? nb + 1 : 0; + } + } + + for (sb = bound; sb < 32; ++sb) { + nb = mad_bit_read(&stream->ptr, 4); + + if (nb == 15) { + stream->error = MAD_ERROR_BADBITALLOC; + return -1; + } + + allocation[0][sb] = + allocation[1][sb] = nb ? nb + 1 : 0; + } + + /* decode scalefactors */ + + for (sb = 0; sb < 32; ++sb) { + for (ch = 0; ch < nch; ++ch) { + if (allocation[ch][sb]) { + scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6); + + if (scalefactor[ch][sb] == 63) { + stream->error = MAD_ERROR_BADSCALEFACTOR; + return -1; + } + } + } + } + + /* decode samples */ + + for (s = 0; s < 12; ++s) { + for (sb = 0; sb < bound; ++sb) { + for (ch = 0; ch < nch; ++ch) { + nb = allocation[ch][sb]; + frame->sbsample[ch][s][sb] = nb ? + mad_f_mul(I_sample(&stream->ptr, nb), + sf_table[scalefactor[ch][sb]]) : 0; + } + } + + for (sb = bound; sb < 32; ++sb) { + if ((nb = allocation[0][sb])) { + mad_fixed_t sample; + + sample = I_sample(&stream->ptr, nb); + + for (ch = 0; ch < nch; ++ch) { + frame->sbsample[ch][s][sb] = + mad_f_mul(sample, sf_table[scalefactor[ch][sb]]); + } + } + else { + for (ch = 0; ch < nch; ++ch) + frame->sbsample[ch][s][sb] = 0; + } + } + } + + return 0; +} + +/* --- Layer II ------------------------------------------------------------ */ + +/* possible quantization per subband table */ +static +struct { + unsigned int sblimit; + unsigned char const offsets[30]; +} const sbquant_table[5] = { + /* ISO/IEC 11172-3 Table B.2a */ + { 27, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 0 */ + 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 } }, + /* ISO/IEC 11172-3 Table B.2b */ + { 30, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 1 */ + 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0 } }, + /* ISO/IEC 11172-3 Table B.2c */ + { 8, { 5, 5, 2, 2, 2, 2, 2, 2 } }, /* 2 */ + /* ISO/IEC 11172-3 Table B.2d */ + { 12, { 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }, /* 3 */ + /* ISO/IEC 13818-3 Table B.1 */ + { 30, { 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, /* 4 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } } +}; + +/* bit allocation table */ +static +struct { + unsigned short nbal; + unsigned short offset; +} const bitalloc_table[8] = { + { 2, 0 }, /* 0 */ + { 2, 3 }, /* 1 */ + { 3, 3 }, /* 2 */ + { 3, 1 }, /* 3 */ + { 4, 2 }, /* 4 */ + { 4, 3 }, /* 5 */ + { 4, 4 }, /* 6 */ + { 4, 5 } /* 7 */ +}; + +/* offsets into quantization class table */ +static +unsigned char const offset_table[6][15] = { + { 0, 1, 16 }, /* 0 */ + { 0, 1, 2, 3, 4, 5, 16 }, /* 1 */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, /* 2 */ + { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* 3 */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }, /* 4 */ + { 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } /* 5 */ +}; + +/* quantization class table */ +static +struct quantclass { + unsigned short nlevels; + unsigned char group; + unsigned char bits; + mad_fixed_t C; + mad_fixed_t D; +} const qc_table[17] = { +# include "qc_table.dat" +}; + +/* + * NAME: II_samples() + * DESCRIPTION: decode three requantized Layer II samples from a bitstream + */ +static +void II_samples(struct mad_bitptr *ptr, + struct quantclass const *quantclass, + mad_fixed_t output[3]) +{ + unsigned int nb, s, sample[3]; + + if ((nb = quantclass->group)) { + unsigned int c, nlevels; + + /* degrouping */ + c = mad_bit_read(ptr, quantclass->bits); + nlevels = quantclass->nlevels; + + for (s = 0; s < 3; ++s) { + sample[s] = c % nlevels; + c /= nlevels; + } + } + else { + nb = quantclass->bits; + + for (s = 0; s < 3; ++s) + sample[s] = mad_bit_read(ptr, nb); + } + + for (s = 0; s < 3; ++s) { + mad_fixed_t requantized; + + /* invert most significant bit, extend sign, then scale to fixed format */ + + requantized = sample[s] ^ (1 << (nb - 1)); + requantized |= -(requantized & (1 << (nb - 1))); + + requantized <<= MAD_F_FRACBITS - (nb - 1); + + /* requantize the sample */ + + /* s'' = C * (s''' + D) */ + + output[s] = mad_f_mul(requantized + quantclass->D, quantclass->C); + + /* s' = factor * s'' */ + /* (to be performed by caller) */ + } +} + +/* + * NAME: layer->II() + * DESCRIPTION: decode a single Layer II frame + */ +int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame) +{ + struct mad_header *header = &frame->header; + struct mad_bitptr start; + unsigned int index, sblimit, nbal, nch, bound, gr, ch, s, sb; + unsigned char const *offsets; + unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3]; + mad_fixed_t samples[3]; + + nch = MAD_NCHANNELS(header); + + if (header->flags & MAD_FLAG_LSF_EXT) + index = 4; + else { + switch (nch == 2 ? header->bitrate / 2 : header->bitrate) { + case 32000: + case 48000: + index = (header->samplerate == 32000) ? 3 : 2; + break; + + case 56000: + case 64000: + case 80000: + index = 0; + break; + + default: + index = (header->samplerate == 48000) ? 0 : 1; + } + } + + sblimit = sbquant_table[index].sblimit; + offsets = sbquant_table[index].offsets; + + bound = 32; + if (header->mode == MAD_MODE_JOINT_STEREO) { + header->flags |= MAD_FLAG_I_STEREO; + bound = 4 + header->mode_extension * 4; + } + + if (bound > sblimit) + bound = sblimit; + + start = stream->ptr; + + /* decode bit allocations */ + + for (sb = 0; sb < bound; ++sb) { + nbal = bitalloc_table[offsets[sb]].nbal; + + for (ch = 0; ch < nch; ++ch) + allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal); + } + + for (sb = bound; sb < sblimit; ++sb) { + nbal = bitalloc_table[offsets[sb]].nbal; + + allocation[0][sb] = + allocation[1][sb] = mad_bit_read(&stream->ptr, nbal); + } + + /* decode scalefactor selection info */ + + for (sb = 0; sb < sblimit; ++sb) { + for (ch = 0; ch < nch; ++ch) { + if (allocation[ch][sb]) + scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2); + } + } + + /* check CRC word */ + + if (header->flags & MAD_FLAG_PROTECTION) { + header->crc_check = + mad_bit_crc(start, mad_bit_length(&start, &stream->ptr), + header->crc_check); + + if (header->crc_check != header->crc_target && + !(frame->options & MAD_OPTION_IGNORECRC)) { + stream->error = MAD_ERROR_BADCRC; + return -1; + } + } + + /* decode scalefactors */ + + for (sb = 0; sb < sblimit; ++sb) { + for (ch = 0; ch < nch; ++ch) { + if (allocation[ch][sb]) { + scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6); + + switch (scfsi[ch][sb]) { + case 2: + scalefactor[ch][sb][2] = + scalefactor[ch][sb][1] = + scalefactor[ch][sb][0]; + break; + + case 0: + scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6); + /* fall through */ + + case 1: + case 3: + scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6); + } + + if (scfsi[ch][sb] & 1) + scalefactor[ch][sb][1] = scalefactor[ch][sb][scfsi[ch][sb] - 1]; + + if (scalefactor[ch][sb][0] == 63 || + scalefactor[ch][sb][1] == 63 || + scalefactor[ch][sb][2] == 63) { + stream->error = MAD_ERROR_BADSCALEFACTOR; + return -1; + } + } + } + } + + /* decode samples */ + + for (gr = 0; gr < 12; ++gr) { + for (sb = 0; sb < bound; ++sb) { + for (ch = 0; ch < nch; ++ch) { + if ((index = allocation[ch][sb])) { + index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1]; + + II_samples(&stream->ptr, &qc_table[index], samples); + + for (s = 0; s < 3; ++s) { + frame->sbsample[ch][3 * gr + s][sb] = + mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]); + } + } + else { + for (s = 0; s < 3; ++s) + frame->sbsample[ch][3 * gr + s][sb] = 0; + } + } + } + + for (sb = bound; sb < sblimit; ++sb) { + if ((index = allocation[0][sb])) { + index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1]; + + II_samples(&stream->ptr, &qc_table[index], samples); + + for (ch = 0; ch < nch; ++ch) { + for (s = 0; s < 3; ++s) { + frame->sbsample[ch][3 * gr + s][sb] = + mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]); + } + } + } + else { + for (ch = 0; ch < nch; ++ch) { + for (s = 0; s < 3; ++s) + frame->sbsample[ch][3 * gr + s][sb] = 0; + } + } + } + + for (ch = 0; ch < nch; ++ch) { + for (s = 0; s < 3; ++s) { + for (sb = sblimit; sb < 32; ++sb) + frame->sbsample[ch][3 * gr + s][sb] = 0; + } + } + } + + return 0; +} diff --git a/core/multimedia/opieplayer/libmad/layer12.h b/core/multimedia/opieplayer/libmad/layer12.h new file mode 100644 index 0000000..d2c81ac --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/layer12.h @@ -0,0 +1,31 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_LAYER12_H +# define LIBMAD_LAYER12_H + +# include "stream.h" +# include "frame.h" + +int mad_layer_I(struct mad_stream *, struct mad_frame *); +int mad_layer_II(struct mad_stream *, struct mad_frame *); + +# endif diff --git a/core/multimedia/opieplayer/libmad/layer3.c b/core/multimedia/opieplayer/libmad/layer3.c new file mode 100644 index 0000000..194fc7e --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/layer3.c @@ -0,0 +1,2492 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# include +# include +# include + +# ifdef HAVE_LIMITS_H +# include +# else +# define CHAR_BIT 8 +# endif + +# include "fixed.h" +# include "bit.h" +# include "stream.h" +# include "frame.h" +# include "huffman.h" +# include "layer3.h" + +/* --- Layer III ----------------------------------------------------------- */ + +enum { + count1table_select = 0x01, + scalefac_scale = 0x02, + preflag = 0x04, + mixed_block_flag = 0x08 +}; + +struct sideinfo { + unsigned int main_data_begin; + unsigned int private_bits; + + unsigned char scfsi[2]; + + struct granule { + struct channel { + /* from side info */ + unsigned short part2_3_length; + unsigned short big_values; + unsigned short global_gain; + unsigned short scalefac_compress; + + unsigned char flags; + unsigned char block_type; + unsigned char table_select[3]; + unsigned char subblock_gain[3]; + unsigned char region0_count; + unsigned char region1_count; + + /* from main_data */ + unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */ + } ch[2]; + } gr[2]; +}; + +/* + * scalefactor bit lengths + * derived from section 2.4.2.7 of ISO/IEC 11172-3 + */ +static +struct { + unsigned char slen1; + unsigned char slen2; +} const sflen_table[16] = { + { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, + { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 }, + { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 } +}; + +/* + * number of LSF scalefactor band values + * derived from section 2.4.3.2 of ISO/IEC 13818-3 + */ +static +unsigned char const nsfb_table[6][3][4] = { + { { 6, 5, 5, 5 }, + { 9, 9, 9, 9 }, + { 6, 9, 9, 9 } }, + + { { 6, 5, 7, 3 }, + { 9, 9, 12, 6 }, + { 6, 9, 12, 6 } }, + + { { 11, 10, 0, 0 }, + { 18, 18, 0, 0 }, + { 15, 18, 0, 0 } }, + + { { 7, 7, 7, 0 }, + { 12, 12, 12, 0 }, + { 6, 15, 12, 0 } }, + + { { 6, 6, 6, 3 }, + { 12, 9, 9, 6 }, + { 6, 12, 9, 6 } }, + + { { 8, 8, 5, 0 }, + { 15, 12, 9, 0 }, + { 6, 18, 9, 0 } } +}; + +/* + * MPEG-1 scalefactor band widths + * derived from Table B.8 of ISO/IEC 11172-3 + */ +static +unsigned char const sfb_48000_long[] = { + 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, + 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192 +}; + +static +unsigned char const sfb_44100_long[] = { + 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, + 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158 +}; + +static +unsigned char const sfb_32000_long[] = { + 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, + 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26 +}; + +static +unsigned char const sfb_48000_short[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, + 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14, + 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 +}; + +static +unsigned char const sfb_44100_short[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, + 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, + 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 +}; + +static +unsigned char const sfb_32000_short[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, + 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, + 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 +}; + +static +unsigned char const sfb_48000_mixed[] = { + /* long */ 4, 4, 4, 4, 4, 4, 6, 6, + /* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10, + 10, 10, 12, 12, 12, 14, 14, 14, 16, 16, + 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 +}; + +static +unsigned char const sfb_44100_mixed[] = { + /* long */ 4, 4, 4, 4, 4, 4, 6, 6, + /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, + 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, + 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 +}; + +static +unsigned char const sfb_32000_mixed[] = { + /* long */ 4, 4, 4, 4, 4, 4, 6, 6, + /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12, + 12, 12, 16, 16, 16, 20, 20, 20, 26, 26, + 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 +}; + +/* + * MPEG-2 scalefactor band widths + * derived from Table B.2 of ISO/IEC 13818-3 + */ +static +unsigned char const sfb_24000_long[] = { + 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36 +}; + +static +unsigned char const sfb_22050_long[] = { + 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54 +}; + +# define sfb_16000_long sfb_22050_long + +static +unsigned char const sfb_24000_short[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, + 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, + 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 +}; + +static +unsigned char const sfb_22050_short[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, + 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18, + 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 +}; + +static +unsigned char const sfb_16000_short[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, + 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, + 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 +}; + +static +unsigned char const sfb_24000_mixed[] = { + /* long */ 6, 6, 6, 6, 6, 6, + /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, + 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, + 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 +}; + +static +unsigned char const sfb_22050_mixed[] = { + /* long */ 6, 6, 6, 6, 6, 6, + /* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, + 10, 10, 14, 14, 14, 18, 18, 18, 26, 26, + 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 +}; + +static +unsigned char const sfb_16000_mixed[] = { + /* long */ 6, 6, 6, 6, 6, 6, + /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, + 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, + 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 +}; + +/* + * MPEG 2.5 scalefactor band widths + * derived from public sources + */ +# define sfb_12000_long sfb_16000_long +# define sfb_11025_long sfb_12000_long + +static +unsigned char const sfb_8000_long[] = { + 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, + 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2 +}; + +# define sfb_12000_short sfb_16000_short +# define sfb_11025_short sfb_12000_short + +static +unsigned char const sfb_8000_short[] = { + 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16, + 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, + 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 +}; + +# define sfb_12000_mixed sfb_16000_mixed +# define sfb_11025_mixed sfb_12000_mixed + +/* the 8000 Hz short block scalefactor bands do not break after the first 36 + frequency lines, so this is probably wrong */ +static +unsigned char const sfb_8000_mixed[] = { + /* long */ 12, 12, 12, + /* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16, + 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 +}; + +static +struct { + unsigned char const *l; + unsigned char const *s; + unsigned char const *m; +} const sfbwidth_table[9] = { + { sfb_48000_long, sfb_48000_short, sfb_48000_mixed }, + { sfb_44100_long, sfb_44100_short, sfb_44100_mixed }, + { sfb_32000_long, sfb_32000_short, sfb_32000_mixed }, + { sfb_24000_long, sfb_24000_short, sfb_24000_mixed }, + { sfb_22050_long, sfb_22050_short, sfb_22050_mixed }, + { sfb_16000_long, sfb_16000_short, sfb_16000_mixed }, + { sfb_12000_long, sfb_12000_short, sfb_12000_mixed }, + { sfb_11025_long, sfb_11025_short, sfb_11025_mixed }, + { sfb_8000_long, sfb_8000_short, sfb_8000_mixed } +}; + +/* + * scalefactor band preemphasis (used only when preflag is set) + * derived from Table B.6 of ISO/IEC 11172-3 + */ +static +unsigned char const pretab[22] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 +}; + +/* + * table for requantization + * + * rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3) + */ +static +struct fixedfloat { + unsigned long mantissa : 27; + unsigned short exponent : 5; +} const rq_table[8207] = { +# include "rq_table.dat" +}; + +/* + * fractional powers of two + * used for requantization and joint stereo decoding + * + * root_table[3 + x] = 2^(x/4) + */ +static +mad_fixed_t const root_table[7] = { + MAD_F(0x09837f05) /* 2^(-3/4) == 0.59460355750136 */, + MAD_F(0x0b504f33) /* 2^(-2/4) == 0.70710678118655 */, + MAD_F(0x0d744fcd) /* 2^(-1/4) == 0.84089641525371 */, + MAD_F(0x10000000) /* 2^( 0/4) == 1.00000000000000 */, + MAD_F(0x1306fe0a) /* 2^(+1/4) == 1.18920711500272 */, + MAD_F(0x16a09e66) /* 2^(+2/4) == 1.41421356237310 */, + MAD_F(0x1ae89f99) /* 2^(+3/4) == 1.68179283050743 */ +}; + +/* + * coefficients for aliasing reduction + * derived from Table B.9 of ISO/IEC 11172-3 + * + * c[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 } + * cs[i] = 1 / sqrt(1 + c[i]^2) + * ca[i] = c[i] / sqrt(1 + c[i]^2) + */ +static +mad_fixed_t const cs[8] = { + +MAD_F(0x0db84a81) /* +0.857492926 */, +MAD_F(0x0e1b9d7f) /* +0.881741997 */, + +MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */, + +MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */, + +MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */ +}; + +static +mad_fixed_t const ca[8] = { + -MAD_F(0x083b5fe7) /* -0.514495755 */, -MAD_F(0x078c36d2) /* -0.471731969 */, + -MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */, + -MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */, + -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */ +}; + +/* + * IMDCT coefficients for short blocks + * derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3 + * + * imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1)) + * imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1)) + */ +static +mad_fixed_t const imdct_s[6][6] = { +# include "imdct_s.dat" +}; + +# if !defined(ASO_IMDCT) +/* + * windowing coefficients for long blocks + * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 + * + * window_l[i] = sin((PI / 36) * (i + 1/2)) + */ +static +mad_fixed_t const window_l[36] = { + MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */, + MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */, + MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */, + MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, + MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x0bcbe352) /* 0.737277337 */, + MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0d7e8807) /* 0.843391446 */, + + MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0ec835e8) /* 0.923879533 */, + MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0f9ee890) /* 0.976296007 */, + MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ffc19fd) /* 0.999048222 */, + MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0fdcf549) /* 0.991444861 */, + MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0f426cb5) /* 0.953716951 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0e313245) /* 0.887010833 */, + + MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0cb19346) /* 0.793353340 */, + MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0acf37ad) /* 0.675590208 */, + MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0898c779) /* 0.537299608 */, + MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x061f78aa) /* 0.382683432 */, + MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x03768962) /* 0.216439614 */, + MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x00b2aa3e) /* 0.043619387 */, +}; +# endif /* ASO_IMDCT */ + +/* + * windowing coefficients for short blocks + * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 + * + * window_s[i] = sin((PI / 12) * (i + 1/2)) + */ +static +mad_fixed_t const window_s[12] = { + MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */, + MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */, + MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ec835e8) /* 0.923879533 */, + MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, + MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */, +}; + +/* + * coefficients for intensity stereo processing + * derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3 + * + * is_ratio[i] = tan(i * (PI / 12)) + * is_table[i] = is_ratio[i] / (1 + is_ratio[i]) + */ +static +mad_fixed_t const is_table[7] = { + MAD_F(0x00000000) /* 0.000000000 */, + MAD_F(0x0361962f) /* 0.211324865 */, + MAD_F(0x05db3d74) /* 0.366025404 */, + MAD_F(0x08000000) /* 0.500000000 */, + MAD_F(0x0a24c28c) /* 0.633974596 */, + MAD_F(0x0c9e69d1) /* 0.788675135 */, + MAD_F(0x10000000) /* 1.000000000 */ +}; + +/* + * coefficients for LSF intensity stereo processing + * derived from section 2.4.3.2 of ISO/IEC 13818-3 + * + * is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1) + * is_lsf_table[1][i] = (1 / sqrt(2))^(i + 1) + */ +static +mad_fixed_t const is_lsf_table[2][15] = { + { + MAD_F(0x0d744fcd) /* 0.840896415 */, + MAD_F(0x0b504f33) /* 0.707106781 */, + MAD_F(0x09837f05) /* 0.594603558 */, + MAD_F(0x08000000) /* 0.500000000 */, + MAD_F(0x06ba27e6) /* 0.420448208 */, + MAD_F(0x05a8279a) /* 0.353553391 */, + MAD_F(0x04c1bf83) /* 0.297301779 */, + MAD_F(0x04000000) /* 0.250000000 */, + MAD_F(0x035d13f3) /* 0.210224104 */, + MAD_F(0x02d413cd) /* 0.176776695 */, + MAD_F(0x0260dfc1) /* 0.148650889 */, + MAD_F(0x02000000) /* 0.125000000 */, + MAD_F(0x01ae89fa) /* 0.105112052 */, + MAD_F(0x016a09e6) /* 0.088388348 */, + MAD_F(0x01306fe1) /* 0.074325445 */ + }, { + MAD_F(0x0b504f33) /* 0.707106781 */, + MAD_F(0x08000000) /* 0.500000000 */, + MAD_F(0x05a8279a) /* 0.353553391 */, + MAD_F(0x04000000) /* 0.250000000 */, + MAD_F(0x02d413cd) /* 0.176776695 */, + MAD_F(0x02000000) /* 0.125000000 */, + MAD_F(0x016a09e6) /* 0.088388348 */, + MAD_F(0x01000000) /* 0.062500000 */, + MAD_F(0x00b504f3) /* 0.044194174 */, + MAD_F(0x00800000) /* 0.031250000 */, + MAD_F(0x005a827a) /* 0.022097087 */, + MAD_F(0x00400000) /* 0.015625000 */, + MAD_F(0x002d413d) /* 0.011048543 */, + MAD_F(0x00200000) /* 0.007812500 */, + MAD_F(0x0016a09e) /* 0.005524272 */ + } +}; + +/* + * NAME: III_sideinfo() + * DESCRIPTION: decode frame side information from a bitstream + */ +static +enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch, + int lsf, struct sideinfo *si, + unsigned int *data_bitlen, + unsigned int *priv_bitlen) +{ + unsigned int ngr, gr, ch, i; + enum mad_error result = 0; + + *data_bitlen = 0; + *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3); + + si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9); + si->private_bits = mad_bit_read(ptr, *priv_bitlen); + + ngr = 1; + if (!lsf) { + ngr = 2; + + for (ch = 0; ch < nch; ++ch) + si->scfsi[ch] = mad_bit_read(ptr, 4); + } + + for (gr = 0; gr < ngr; ++gr) { + struct granule *granule = &si->gr[gr]; + + for (ch = 0; ch < nch; ++ch) { + struct channel *channel = &granule->ch[ch]; + + channel->part2_3_length = mad_bit_read(ptr, 12); + channel->big_values = mad_bit_read(ptr, 9); + channel->global_gain = mad_bit_read(ptr, 8); + channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4); + + *data_bitlen += channel->part2_3_length; + + if (channel->big_values > 288 && result == 0) + result = MAD_ERROR_BADBIGVALUES; + + channel->flags = 0; + + /* window_switching_flag */ + if (mad_bit_read(ptr, 1)) { + channel->block_type = mad_bit_read(ptr, 2); + + if (channel->block_type == 0 && result == 0) + result = MAD_ERROR_BADBLOCKTYPE; + + if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0) + result = MAD_ERROR_BADSCFSI; + + channel->region0_count = 7; + channel->region1_count = 36; + + if (mad_bit_read(ptr, 1)) + channel->flags |= mixed_block_flag; + else if (channel->block_type == 2) + channel->region0_count = 8; + + for (i = 0; i < 2; ++i) + channel->table_select[i] = mad_bit_read(ptr, 5); + +# if defined(DEBUG) + channel->table_select[2] = 4; /* not used */ +# endif + + for (i = 0; i < 3; ++i) + channel->subblock_gain[i] = mad_bit_read(ptr, 3); + } + else { + channel->block_type = 0; + + for (i = 0; i < 3; ++i) + channel->table_select[i] = mad_bit_read(ptr, 5); + + channel->region0_count = mad_bit_read(ptr, 4); + channel->region1_count = mad_bit_read(ptr, 3); + } + + /* [preflag,] scalefac_scale, count1table_select */ + channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3); + } + } + + return result; +} + +/* + * NAME: III_scalefactors_lsf() + * DESCRIPTION: decode channel scalefactors for LSF from a bitstream + */ +static +unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr, + struct channel *channel, + struct channel *gr1ch, int mode_extension) +{ + struct mad_bitptr start; + unsigned int scalefac_compress, index, slen[4], part, n, i; + unsigned char const *nsfb; + + start = *ptr; + + scalefac_compress = channel->scalefac_compress; + index = (channel->block_type == 2) ? + ((channel->flags & mixed_block_flag) ? 2 : 1) : 0; + + if (!((mode_extension & 0x1) && gr1ch)) { + if (scalefac_compress < 400) { + slen[0] = (scalefac_compress >> 4) / 5; + slen[1] = (scalefac_compress >> 4) % 5; + slen[2] = (scalefac_compress % 16) >> 2; + slen[3] = scalefac_compress % 4; + + nsfb = nsfb_table[0][index]; + } + else if (scalefac_compress < 500) { + scalefac_compress -= 400; + + slen[0] = (scalefac_compress >> 2) / 5; + slen[1] = (scalefac_compress >> 2) % 5; + slen[2] = scalefac_compress % 4; + slen[3] = 0; + + nsfb = nsfb_table[1][index]; + } + else { + scalefac_compress -= 500; + + slen[0] = scalefac_compress / 3; + slen[1] = scalefac_compress % 3; + slen[2] = 0; + slen[3] = 0; + + channel->flags |= preflag; + + nsfb = nsfb_table[2][index]; + } + + n = 0; + for (part = 0; part < 4; ++part) { + for (i = 0; i < nsfb[part]; ++i) + channel->scalefac[n++] = mad_bit_read(ptr, slen[part]); + } + + while (n < 39) + channel->scalefac[n++] = 0; + } + else { /* (mode_extension & 0x1) && gr1ch (i.e. ch == 1) */ + scalefac_compress >>= 1; + + if (scalefac_compress < 180) { + slen[0] = scalefac_compress / 36; + slen[1] = (scalefac_compress % 36) / 6; + slen[2] = (scalefac_compress % 36) % 6; + slen[3] = 0; + + nsfb = nsfb_table[3][index]; + } + else if (scalefac_compress < 244) { + scalefac_compress -= 180; + + slen[0] = (scalefac_compress % 64) >> 4; + slen[1] = (scalefac_compress % 16) >> 2; + slen[2] = scalefac_compress % 4; + slen[3] = 0; + + nsfb = nsfb_table[4][index]; + } + else { + scalefac_compress -= 244; + + slen[0] = scalefac_compress / 3; + slen[1] = scalefac_compress % 3; + slen[2] = 0; + slen[3] = 0; + + nsfb = nsfb_table[5][index]; + } + + n = 0; + for (part = 0; part < 4; ++part) { + unsigned int max, is_pos; + + max = (1 << slen[part]) - 1; + + for (i = 0; i < nsfb[part]; ++i) { + is_pos = mad_bit_read(ptr, slen[part]); + + channel->scalefac[n] = is_pos; + gr1ch->scalefac[n++] = (is_pos == max); + } + } + + while (n < 39) { + channel->scalefac[n] = 0; + gr1ch->scalefac[n++] = 0; /* apparently not illegal */ + } + } + + return mad_bit_length(&start, ptr); +} + +/* + * NAME: III_scalefactors() + * DESCRIPTION: decode channel scalefactors of one granule from a bitstream + */ +static +unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel, + struct channel const *gr0ch, unsigned int scfsi) +{ + struct mad_bitptr start; + unsigned int slen1, slen2, sfbi; + + start = *ptr; + + slen1 = sflen_table[channel->scalefac_compress].slen1; + slen2 = sflen_table[channel->scalefac_compress].slen2; + + if (channel->block_type == 2) { + unsigned int nsfb; + + sfbi = 0; + + nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3; + while (nsfb--) + channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1); + + nsfb = 6 * 3; + while (nsfb--) + channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2); + + nsfb = 1 * 3; + while (nsfb--) + channel->scalefac[sfbi++] = 0; + } + else { /* channel->block_type != 2 */ + if (scfsi & 0x8) { + for (sfbi = 0; sfbi < 6; ++sfbi) + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; + } + else { + for (sfbi = 0; sfbi < 6; ++sfbi) + channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); + } + + if (scfsi & 0x4) { + for (sfbi = 6; sfbi < 11; ++sfbi) + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; + } + else { + for (sfbi = 6; sfbi < 11; ++sfbi) + channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); + } + + if (scfsi & 0x2) { + for (sfbi = 11; sfbi < 16; ++sfbi) + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; + } + else { + for (sfbi = 11; sfbi < 16; ++sfbi) + channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); + } + + if (scfsi & 0x1) { + for (sfbi = 16; sfbi < 21; ++sfbi) + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; + } + else { + for (sfbi = 16; sfbi < 21; ++sfbi) + channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); + } + + channel->scalefac[21] = 0; + } + + return mad_bit_length(&start, ptr); +} + +/* + * NAME: III_exponents() + * DESCRIPTION: calculate scalefactor exponents + */ +static +void III_exponents(struct channel const *channel, + unsigned char const *sfbwidth, signed int exponents[39]) +{ + signed int gain; + unsigned int scalefac_multiplier, sfbi; + + gain = (signed int) channel->global_gain - 210; + scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1; + + if (channel->block_type == 2) { + unsigned int l; + signed int gain0, gain1, gain2; + + sfbi = l = 0; + + if (channel->flags & mixed_block_flag) { + unsigned int premask; + + premask = (channel->flags & preflag) ? ~0 : 0; + + /* long block subbands 0-1 */ + + while (l < 36) { + exponents[sfbi] = gain - + (signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) << + scalefac_multiplier); + + l += sfbwidth[sfbi++]; + } + } + + /* this is probably wrong for 8000 Hz short/mixed blocks */ + + gain0 = gain - 8 * (signed int) channel->subblock_gain[0]; + gain1 = gain - 8 * (signed int) channel->subblock_gain[1]; + gain2 = gain - 8 * (signed int) channel->subblock_gain[2]; + + while (l < 576) { + exponents[sfbi + 0] = gain0 - + (signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier); + exponents[sfbi + 1] = gain1 - + (signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier); + exponents[sfbi + 2] = gain2 - + (signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier); + + l += 3 * sfbwidth[sfbi]; + sfbi += 3; + } + } + else { /* channel->block_type != 2 */ + if (channel->flags & preflag) { + for (sfbi = 0; sfbi < 22; ++sfbi) { + exponents[sfbi] = gain - + (signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) << + scalefac_multiplier); + } + } + else { + for (sfbi = 0; sfbi < 22; ++sfbi) { + exponents[sfbi] = gain - + (signed int) (channel->scalefac[sfbi] << scalefac_multiplier); + } + } + } +} + +/* + * NAME: III_requantize() + * DESCRIPTION: requantize one (positive) value + */ +static +mad_fixed_t III_requantize(unsigned int value, signed int exp) +{ + mad_fixed_t requantized; + signed int frac; + struct fixedfloat const *power; + + /* + * long blocks: + * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * + * 2^((1/4) * (global_gain - 210)) * + * 2^-(scalefac_multiplier * + * (scalefac_l[sfb] + preflag * pretab[sfb])) + * + * short blocks: + * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * + * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) * + * 2^-(scalefac_multiplier * scalefac_s[sfb][w]) + * + * where: + * scalefac_multiplier = (scalefac_scale + 1) / 2 + */ + + frac = exp % 4; + exp /= 4; + + power = &rq_table[value]; + requantized = power->mantissa; + exp += power->exponent; + + if (exp < 0) { + if (-exp >= sizeof(mad_fixed_t) * CHAR_BIT) { + /* underflow */ + requantized = 0; + } + else + requantized >>= -exp; + } + else { + if (exp >= 5) { + /* overflow */ +# if defined(DEBUG) + fprintf(stderr, "requantize overflow (%f * 2^%d)\n", + mad_f_todouble(requantized), exp); +# endif + requantized = MAD_F_MAX; + } + else + requantized <<= exp; + } + + return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized; +} + +/* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */ +# define MASK(cache, sz, bits) \ + (((cache) >> ((sz) - (bits))) & ((1 << (bits)) - 1)) +# define MASK1BIT(cache, sz) \ + ((cache) & (1 << ((sz) - 1))) + +/* + * NAME: III_huffdecode() + * DESCRIPTION: decode Huffman code words of one channel of one granule + */ +static +enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576], + struct channel *channel, + unsigned char const *sfbwidth, + unsigned int part2_length) +{ + signed int exponents[39], exp; + signed int const *expptr; + struct mad_bitptr peek; + signed int bits_left, cachesz; + register mad_fixed_t *xrptr; + mad_fixed_t const *sfbound; + register unsigned long bitcache; + + bits_left = (signed) channel->part2_3_length - (signed) part2_length; + if (bits_left < 0) + return MAD_ERROR_BADPART3LEN; + + III_exponents(channel, sfbwidth, exponents); + + peek = *ptr; + mad_bit_skip(ptr, bits_left); + + /* align bit reads to byte boundaries */ + cachesz = mad_bit_bitsleft(&peek); + cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7; + + bitcache = mad_bit_read(&peek, cachesz); + bits_left -= cachesz; + + xrptr = &xr[0]; + + /* big_values */ + { + unsigned int region, rcount; + struct hufftable const *entry; + union huffpair const *table; + unsigned int linbits, startbits, big_values, reqhits; + mad_fixed_t reqcache[16]; + + sfbound = xrptr + *sfbwidth++; + rcount = channel->region0_count + 1; + + entry = &mad_huff_pair_table[channel->table_select[region = 0]]; + table = entry->table; + linbits = entry->linbits; + startbits = entry->startbits; + + if (table == 0) + return MAD_ERROR_BADHUFFTABLE; + + expptr = &exponents[0]; + exp = *expptr++; + reqhits = 0; + + big_values = channel->big_values; + + while (big_values-- && cachesz + bits_left > 0) { + union huffpair const *pair; + unsigned int clumpsz, value; + register mad_fixed_t requantized; + + if (xrptr == sfbound) { + sfbound += *sfbwidth++; + + /* change table if region boundary */ + + if (--rcount == 0) { + if (region == 0) + rcount = channel->region1_count + 1; + else + rcount = 0; /* all remaining */ + + entry = &mad_huff_pair_table[channel->table_select[++region]]; + table = entry->table; + linbits = entry->linbits; + startbits = entry->startbits; + + if (table == 0) + return MAD_ERROR_BADHUFFTABLE; + } + + if (exp != *expptr) { + exp = *expptr; + reqhits = 0; + } + + ++expptr; + } + + if (cachesz < 21) { + unsigned int bits; + + bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7; + bitcache = (bitcache << bits) | mad_bit_read(&peek, bits); + cachesz += bits; + bits_left -= bits; + } + + /* hcod (0..19) */ + + clumpsz = startbits; + pair = &table[MASK(bitcache, cachesz, clumpsz)]; + + while (!pair->final) { + cachesz -= clumpsz; + + clumpsz = pair->ptr.bits; + pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)]; + } + + cachesz -= pair->value.hlen; + + if (linbits) { + /* x (0..14) */ + + value = pair->value.x; + + switch (value) { + case 0: + xrptr[0] = 0; + break; + + case 15: + if (cachesz < linbits + 2) { + bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); + cachesz += 16; + bits_left -= 16; + } + + value += MASK(bitcache, cachesz, linbits); + cachesz -= linbits; + + requantized = III_requantize(value, exp); + goto x_final; + + default: + if (reqhits & (1 << value)) + requantized = reqcache[value]; + else { + reqhits |= (1 << value); + requantized = reqcache[value] = III_requantize(value, exp); + } + + x_final: + xrptr[0] = MASK1BIT(bitcache, cachesz--) ? + -requantized : requantized; + } + + /* y (0..14) */ + + value = pair->value.y; + + switch (value) { + case 0: + xrptr[1] = 0; + break; + + case 15: + if (cachesz < linbits + 1) { + bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); + cachesz += 16; + bits_left -= 16; + } + + value += MASK(bitcache, cachesz, linbits); + cachesz -= linbits; + + requantized = III_requantize(value, exp); + goto y_final; + + default: + if (reqhits & (1 << value)) + requantized = reqcache[value]; + else { + reqhits |= (1 << value); + requantized = reqcache[value] = III_requantize(value, exp); + } + + y_final: + xrptr[1] = MASK1BIT(bitcache, cachesz--) ? + -requantized : requantized; + } + } + else { + /* x (0..1) */ + + value = pair->value.x; + + if (value == 0) + xrptr[0] = 0; + else { + if (reqhits & (1 << value)) + requantized = reqcache[value]; + else { + reqhits |= (1 << value); + requantized = reqcache[value] = III_requantize(value, exp); + } + + xrptr[0] = MASK1BIT(bitcache, cachesz--) ? + -requantized : requantized; + } + + /* y (0..1) */ + + value = pair->value.y; + + if (value == 0) + xrptr[1] = 0; + else { + if (reqhits & (1 << value)) + requantized = reqcache[value]; + else { + reqhits |= (1 << value); + requantized = reqcache[value] = III_requantize(value, exp); + } + + xrptr[1] = MASK1BIT(bitcache, cachesz--) ? + -requantized : requantized; + } + } + + xrptr += 2; + } + } + + if (cachesz + bits_left < 0) + return MAD_ERROR_BADHUFFDATA; /* big_values overrun */ + + /* count1 */ + { + union huffquad const *table; + register mad_fixed_t requantized; + + table = mad_huff_quad_table[channel->flags & count1table_select]; + + requantized = III_requantize(1, exp); + + while (cachesz + bits_left > 0 && xrptr <= &xr[572]) { + union huffquad const *quad; + + /* hcod (1..6) */ + + if (cachesz < 10) { + bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); + cachesz += 16; + bits_left -= 16; + } + + quad = &table[MASK(bitcache, cachesz, 4)]; + + /* quad tables guaranteed to have at most one extra lookup */ + if (!quad->final) { + cachesz -= 4; + + quad = &table[quad->ptr.offset + + MASK(bitcache, cachesz, quad->ptr.bits)]; + } + + cachesz -= quad->value.hlen; + + if (xrptr == sfbound) { + sfbound += *sfbwidth++; + + if (exp != *expptr) { + exp = *expptr; + requantized = III_requantize(1, exp); + } + + ++expptr; + } + + /* v (0..1) */ + + xrptr[0] = quad->value.v ? + (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; + + /* w (0..1) */ + + xrptr[1] = quad->value.w ? + (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; + + xrptr += 2; + + if (xrptr == sfbound) { + sfbound += *sfbwidth++; + + if (exp != *expptr) { + exp = *expptr; + requantized = III_requantize(1, exp); + } + + ++expptr; + } + + /* x (0..1) */ + + xrptr[0] = quad->value.x ? + (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; + + /* y (0..1) */ + + xrptr[1] = quad->value.y ? + (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; + + xrptr += 2; + } + + if (cachesz + bits_left < 0) { +# if 0 && defined(DEBUG) + fprintf(stderr, "huffman count1 overrun (%d bits)\n", + -(cachesz + bits_left)); +# endif + + /* technically the bitstream is misformatted, but apparently + some encoders are just a bit sloppy with stuffing bits */ + + xrptr -= 4; + } + } + + assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT); + +# if 0 && defined(DEBUG) + if (bits_left < 0) + fprintf(stderr, "read %d bits too many\n", -bits_left); + else if (cachesz + bits_left > 0) + fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left); +# endif + + /* rzero */ + while (xrptr < &xr[576]) { + xrptr[0] = 0; + xrptr[1] = 0; + + xrptr += 2; + } + + return 0; +} + +# undef MASK +# undef MASK1BIT + +/* + * NAME: III_reorder() + * DESCRIPTION: reorder frequency lines of a short block into subband order + */ +static +void III_reorder(mad_fixed_t xr[576], struct channel const *channel, + unsigned char const sfbwidth[39]) +{ + mad_fixed_t tmp[32][3][6]; + unsigned int sb, l, sfbi, f, w, sbw[3], sw[3]; + + /* this is probably wrong for 8000 Hz mixed blocks */ + + if (channel->flags & mixed_block_flag) + sb = 2, sfbi = 3 * 3; + else + sb = 0, sfbi = 0; + + for (w = 0; w < 3; ++w) { + sbw[w] = sb; + sw[w] = 0; + } + + f = sfbwidth[sfbi]; + w = 0; + + for (l = 18 * sb; l < 576; ++l) { + tmp[sbw[w]][w][sw[w]++] = xr[l]; + + if (sw[w] == 6) { + sw[w] = 0; + ++sbw[w]; + } + + if (--f == 0) { + if (++w == 3) + w = 0; + + f = sfbwidth[++sfbi]; + } + } + + memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t)); +} + +/* + * NAME: III_stereo() + * DESCRIPTION: perform joint stereo processing on a granule + */ +static +enum mad_error III_stereo(mad_fixed_t xr[2][576], + struct granule const *granule, + struct mad_header *header, + unsigned char const *sfbwidth) +{ + short modes[39]; + unsigned int sfbi, l, n, i; + + enum { + i_stereo = 0x1, + ms_stereo = 0x2 + }; + + if (granule->ch[0].block_type != + granule->ch[1].block_type || + (granule->ch[0].flags & mixed_block_flag) != + (granule->ch[1].flags & mixed_block_flag)) + return MAD_ERROR_BADSTEREO; + + for (i = 0; i < 39; ++i) + modes[i] = header->mode_extension; + + /* intensity stereo */ + + if (header->mode_extension & i_stereo) { + struct channel const *right_ch = &granule->ch[1]; + mad_fixed_t const *right_xr = xr[1]; + unsigned int is_pos; + + header->flags |= MAD_FLAG_I_STEREO; + + /* first determine which scalefactor bands are to be processed */ + + if (right_ch->block_type == 2) { + unsigned int lower, start, max, bound[3], w; + + lower = start = max = bound[0] = bound[1] = bound[2] = 0; + + sfbi = l = 0; + + if (right_ch->flags & mixed_block_flag) { + while (l < 36) { + n = sfbwidth[sfbi++]; + + for (i = 0; i < n; ++i) { + if (right_xr[i]) { + lower = sfbi; + break; + } + } + + right_xr += n; + l += n; + } + + start = sfbi; + } + + w = 0; + while (l < 576) { + n = sfbwidth[sfbi++]; + + for (i = 0; i < n; ++i) { + if (right_xr[i]) { + max = bound[w] = sfbi; + break; + } + } + + right_xr += n; + l += n; + w = (w + 1) % 3; + } + + if (max) + lower = start; + + /* long blocks */ + + for (i = 0; i < lower; ++i) + modes[i] = header->mode_extension & ~i_stereo; + + /* short blocks */ + + w = 0; + for (i = start; i < max; ++i) { + if (i < bound[w]) + modes[i] = header->mode_extension & ~i_stereo; + + w = (w + 1) % 3; + } + } + else { /* right_ch->block_type != 2 */ + unsigned int bound; + + bound = 0; + for (sfbi = l = 0; l < 576; l += n) { + n = sfbwidth[sfbi++]; + + for (i = 0; i < n; ++i) { + if (right_xr[i]) { + bound = sfbi; + break; + } + } + + right_xr += n; + } + + for (i = 0; i < bound; ++i) + modes[i] = header->mode_extension & ~i_stereo; + } + + /* now do the actual processing */ + + if (header->flags & MAD_FLAG_LSF_EXT) { + unsigned char const *illegal_pos = granule[1].ch[1].scalefac; + mad_fixed_t const *lsf_scale; + + /* intensity_scale */ + lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1]; + + for (sfbi = l = 0; l < 576; ++sfbi, l += n) { + n = sfbwidth[sfbi]; + + if (!(modes[sfbi] & i_stereo)) + continue; + + if (illegal_pos[sfbi]) { + modes[sfbi] &= ~i_stereo; + continue; + } + + is_pos = right_ch->scalefac[sfbi]; + + for (i = 0; i < n; ++i) { + register mad_fixed_t left; + + left = xr[0][l + i]; + + if (is_pos == 0) + xr[1][l + i] = left; + else { + register mad_fixed_t opposite; + + opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]); + + if (is_pos & 1) { + xr[0][l + i] = opposite; + xr[1][l + i] = left; + } + else + xr[1][l + i] = opposite; + } + } + } + } + else { /* !(header->flags & MAD_FLAG_LSF_EXT) */ + for (sfbi = l = 0; l < 576; ++sfbi, l += n) { + n = sfbwidth[sfbi]; + + if (!(modes[sfbi] & i_stereo)) + continue; + + is_pos = right_ch->scalefac[sfbi]; + + if (is_pos >= 7) { /* illegal intensity position */ + modes[sfbi] &= ~i_stereo; + continue; + } + + for (i = 0; i < n; ++i) { + register mad_fixed_t left; + + left = xr[0][l + i]; + + xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]); + xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]); + } + } + } + } + + /* middle/side stereo */ + + if (header->mode_extension & ms_stereo) { + register mad_fixed_t invsqrt2; + + header->flags |= MAD_FLAG_MS_STEREO; + + invsqrt2 = root_table[3 + -2]; + + for (sfbi = l = 0; l < 576; ++sfbi, l += n) { + n = sfbwidth[sfbi]; + + if (modes[sfbi] != ms_stereo) + continue; + + for (i = 0; i < n; ++i) { + register mad_fixed_t m, s; + + m = xr[0][l + i]; + s = xr[1][l + i]; + + xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */ + xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */ + } + } + } + + return 0; +} + +/* + * NAME: III_aliasreduce() + * DESCRIPTION: perform frequency line alias reduction + */ +static +void III_aliasreduce(mad_fixed_t xr[576], int lines) +{ + mad_fixed_t const *bound; + int i; + + bound = &xr[lines]; + for (xr += 18; xr < bound; xr += 18) { + for (i = 0; i < 8; ++i) { + register mad_fixed_t *aptr, *bptr, a, b; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + + aptr = &xr[-1 - i]; + bptr = &xr[ i]; + + a = *aptr; + b = *bptr; + +# if defined(ASO_ZEROCHECK) + if (a | b) { +# endif + MAD_F_ML0(hi, lo, a, cs[i]); + MAD_F_MLA(hi, lo, -b, ca[i]); + + *aptr = MAD_F_MLZ(hi, lo); + + MAD_F_ML0(hi, lo, b, cs[i]); + MAD_F_MLA(hi, lo, a, ca[i]); + + *bptr = MAD_F_MLZ(hi, lo); +# if defined(ASO_ZEROCHECK) + } +# endif + } + } +} + +# if defined(ASO_IMDCT) +void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int); +# else +/* + * NAME: imdct36 + * DESCRIPTION: perform X[18]->x[36] IMDCT + */ +static inline +void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36]) +{ + mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; + mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + + MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8)); + MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa)); + + t6 = MAD_F_MLZ(hi, lo); + + MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa)); + MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8)); + + t0 = MAD_F_MLZ(hi, lo); + + MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549)); + + x[7] = MAD_F_MLZ(hi, lo); + x[10] = -x[7]; + + MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0)); + + x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0; + + t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15]; + t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17]; + + MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8)); + MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa)); + + x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0; + + MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346)); + + t1 = MAD_F_MLZ(hi, lo) + t6; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890)); + + x[6] = MAD_F_MLZ(hi, lo) + t1; + x[11] = -x[6]; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2)); + + x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad)); + + x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1; + + MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa)); + MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8)); + + t7 = MAD_F_MLZ(hi, lo); + + MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0)); + + t2 = MAD_F_MLZ(hi, lo); + + MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5)); + + x[5] = MAD_F_MLZ(hi, lo); + x[12] = -x[5]; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352)); + + x[0] = MAD_F_MLZ(hi, lo) + t2; + x[17] = -x[0]; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962)); + + x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2; + + MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549)); + + t3 = MAD_F_MLZ(hi, lo) + t7; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd)); + + x[8] = MAD_F_MLZ(hi, lo) + t3; + x[9] = -x[8]; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284)); + + x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779)); + + x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3; + + MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8)); + MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa)); + + t4 = MAD_F_MLZ(hi, lo) - t7; + + MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa)); + MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8)); + + x[4] = MAD_F_MLZ(hi, lo) + t4; + x[13] = -x[4]; + + MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346)); + + x[1] = MAD_F_MLZ(hi, lo) + t4; + x[16] = -x[1]; + + MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2)); + + x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4; + + MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2)); + + t5 = MAD_F_MLZ(hi, lo) - t6; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807)); + + x[2] = MAD_F_MLZ(hi, lo) + t5; + x[15] = -x[2]; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245)); + + x[3] = MAD_F_MLZ(hi, lo) + t5; + x[14] = -x[3]; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e)); + + x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5; +} + +/* + * NAME: III_imdct_l() + * DESCRIPTION: perform IMDCT and windowing for long blocks + */ +static +void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36], + unsigned int block_type) +{ + unsigned int i; + + /* IMDCT */ + + imdct36(X, z); + + /* windowing */ + + switch (block_type) { + case 0: /* normal window */ +# if defined(ASO_INTERLEAVE1) + { + register mad_fixed_t tmp1, tmp2; + + tmp1 = window_l[0]; + tmp2 = window_l[1]; + + for (i = 0; i < 34; i += 2) { + z[i + 0] = mad_f_mul(z[i + 0], tmp1); + tmp1 = window_l[i + 2]; + z[i + 1] = mad_f_mul(z[i + 1], tmp2); + tmp2 = window_l[i + 3]; + } + + z[34] = mad_f_mul(z[34], tmp1); + z[35] = mad_f_mul(z[35], tmp2); + } +# elif defined(ASO_INTERLEAVE2) + { + register mad_fixed_t tmp1, tmp2; + + tmp1 = z[0]; + tmp2 = window_l[0]; + + for (i = 0; i < 35; ++i) { + z[i] = mad_f_mul(tmp1, tmp2); + tmp1 = z[i + 1]; + tmp2 = window_l[i + 1]; + } + + z[35] = mad_f_mul(tmp1, tmp2); + } +# elif 1 + for (i = 0; i < 36; i += 4) { + z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]); + z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]); + z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]); + z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]); + } +# else + for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]); +# endif + break; + + case 1: /* start block */ + for (i = 0; i < 18; ++i) z[i] = mad_f_mul(z[i], window_l[i]); + /* (i = 18; i < 24; ++i) z[i] unchanged */ + for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]); + for (i = 30; i < 36; ++i) z[i] = 0; + break; + + case 3: /* stop block */ + for (i = 0; i < 6; ++i) z[i] = 0; + for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]); + /* (i = 12; i < 18; ++i) z[i] unchanged */ + for (i = 18; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]); + break; + } +} +# endif /* ASO_IMDCT */ + +/* + * NAME: III_imdct_s() + * DESCRIPTION: perform IMDCT and windowing for short blocks + */ +static +void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36]) +{ + mad_fixed_t y[36], *yptr; + mad_fixed_t const *wptr; + int w, i; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + + /* IMDCT */ + + yptr = &y[0]; + + for (w = 0; w < 3; ++w) { + register mad_fixed_t const (*s)[6]; + + s = imdct_s; + + for (i = 0; i < 3; ++i) { + MAD_F_ML0(hi, lo, X[0], (*s)[0]); + MAD_F_MLA(hi, lo, X[1], (*s)[1]); + MAD_F_MLA(hi, lo, X[2], (*s)[2]); + MAD_F_MLA(hi, lo, X[3], (*s)[3]); + MAD_F_MLA(hi, lo, X[4], (*s)[4]); + MAD_F_MLA(hi, lo, X[5], (*s)[5]); + + yptr[i + 0] = MAD_F_MLZ(hi, lo); + yptr[5 - i] = -yptr[i + 0]; + + ++s; + + MAD_F_ML0(hi, lo, X[0], (*s)[0]); + MAD_F_MLA(hi, lo, X[1], (*s)[1]); + MAD_F_MLA(hi, lo, X[2], (*s)[2]); + MAD_F_MLA(hi, lo, X[3], (*s)[3]); + MAD_F_MLA(hi, lo, X[4], (*s)[4]); + MAD_F_MLA(hi, lo, X[5], (*s)[5]); + + yptr[ i + 6] = MAD_F_MLZ(hi, lo); + yptr[11 - i] = yptr[i + 6]; + + ++s; + } + + yptr += 12; + X += 6; + } + + /* windowing, overlapping and concatenation */ + + yptr = &y[0]; + wptr = &window_s[0]; + + for (i = 0; i < 6; ++i) { + z[i + 0] = 0; + z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]); + + MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]); + MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]); + + z[i + 12] = MAD_F_MLZ(hi, lo); + + MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]); + MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]); + + z[i + 18] = MAD_F_MLZ(hi, lo); + + z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]); + z[i + 30] = 0; + + ++yptr; + ++wptr; + } +} + +/* + * NAME: III_overlap() + * DESCRIPTION: perform overlap-add of windowed IMDCT outputs + */ +static +void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18], + mad_fixed_t sample[18][32], unsigned int sb) +{ + unsigned int i; + +# if defined(ASO_INTERLEAVE2) + { + register mad_fixed_t tmp1, tmp2; + + tmp1 = overlap[0]; + tmp2 = overlap[1]; + + for (i = 0; i < 16; i += 2) { + sample[i + 0][sb] = output[i + 0] + tmp1; + overlap[i + 0] = output[i + 0 + 18]; + tmp1 = overlap[i + 2]; + + sample[i + 1][sb] = output[i + 1] + tmp2; + overlap[i + 1] = output[i + 1 + 18]; + tmp2 = overlap[i + 3]; + } + + sample[16][sb] = output[16] + tmp1; + overlap[16] = output[16 + 18]; + sample[17][sb] = output[17] + tmp2; + overlap[17] = output[17 + 18]; + } +# elif 0 + for (i = 0; i < 18; i += 2) { + sample[i + 0][sb] = output[i + 0] + overlap[i + 0]; + overlap[i + 0] = output[i + 0 + 18]; + + sample[i + 1][sb] = output[i + 1] + overlap[i + 1]; + overlap[i + 1] = output[i + 1 + 18]; + } +# else + for (i = 0; i < 18; ++i) { + sample[i][sb] = output[i] + overlap[i]; + overlap[i] = output[i + 18]; + } +# endif +} + +/* + * NAME: III_overlap_z() + * DESCRIPTION: perform "overlap-add" of zero IMDCT outputs + */ +static inline +void III_overlap_z(mad_fixed_t overlap[18], + mad_fixed_t sample[18][32], unsigned int sb) +{ + unsigned int i; + +# if defined(ASO_INTERLEAVE2) + { + register mad_fixed_t tmp1, tmp2; + + tmp1 = overlap[0]; + tmp2 = overlap[1]; + + for (i = 0; i < 16; i += 2) { + sample[i + 0][sb] = tmp1; + overlap[i + 0] = 0; + tmp1 = overlap[i + 2]; + + sample[i + 1][sb] = tmp2; + overlap[i + 1] = 0; + tmp2 = overlap[i + 3]; + } + + sample[16][sb] = tmp1; + overlap[16] = 0; + sample[17][sb] = tmp2; + overlap[17] = 0; + } +# else + for (i = 0; i < 18; ++i) { + sample[i][sb] = overlap[i]; + overlap[i] = 0; + } +# endif +} + +/* + * NAME: III_freqinver() + * DESCRIPTION: perform subband frequency inversion for odd sample lines + */ +static +void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb) +{ + unsigned int i; + +# if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2) + { + register mad_fixed_t tmp1, tmp2; + + tmp1 = sample[1][sb]; + tmp2 = sample[3][sb]; + + for (i = 1; i < 13; i += 4) { + sample[i + 0][sb] = -tmp1; + tmp1 = sample[i + 4][sb]; + sample[i + 2][sb] = -tmp2; + tmp2 = sample[i + 6][sb]; + } + + sample[13][sb] = -tmp1; + tmp1 = sample[17][sb]; + sample[15][sb] = -tmp2; + sample[17][sb] = -tmp1; + } +# else + for (i = 1; i < 18; i += 2) + sample[i][sb] = -sample[i][sb]; +# endif +} + +/* + * NAME: III_decode() + * DESCRIPTION: decode frame main_data + */ +static +int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, + struct sideinfo *si, unsigned int nch) +{ + struct mad_header *header = &frame->header; + unsigned int sfreqi, ngr, gr; + + { + unsigned int sfreq; + + sfreq = header->samplerate; + if (header->flags & MAD_FLAG_MPEG_2_5_EXT) + sfreq *= 2; + + /* 48000 => 0, 44100 => 1, 32000 => 2, + 24000 => 3, 22050 => 4, 16000 => 5 */ + sfreqi = ((sfreq >> 7) & 0x000f) + + ((sfreq >> 15) & 0x0001) - 8; + + if (header->flags & MAD_FLAG_MPEG_2_5_EXT) + sfreqi += 3; + } + + /* scalefactors, Huffman decoding, requantization */ + + ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2; + + for (gr = 0; gr < ngr; ++gr) { + struct granule *granule = &si->gr[gr]; + unsigned char const *sfbwidth = 0; + mad_fixed_t xr[2][576]; + unsigned int ch; + enum mad_error error; + + for (ch = 0; ch < nch; ++ch) { + struct channel *channel = &granule->ch[ch]; + unsigned int part2_length; + + sfbwidth = sfbwidth_table[sfreqi].l; + if (channel->block_type == 2) { + sfbwidth = (channel->flags & mixed_block_flag) ? + sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s; + } + + if (header->flags & MAD_FLAG_LSF_EXT) { + part2_length = III_scalefactors_lsf(ptr, channel, + ch == 0 ? 0 : &si->gr[1].ch[1], + header->mode_extension); + } + else { + part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch], + gr == 0 ? 0 : si->scfsi[ch]); + } + + error = III_huffdecode(ptr, xr[ch], channel, sfbwidth, part2_length); + if (error) + return error; + } + + /* joint stereo processing */ + + if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) { + error = III_stereo(xr, granule, header, sfbwidth); + if (error) + return error; + } + + /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */ + + for (ch = 0; ch < nch; ++ch) { + struct channel const *channel = &granule->ch[ch]; + mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr]; + unsigned int sb, l, i, sblimit; + mad_fixed_t output[36]; + + if (channel->block_type == 2) { + III_reorder(xr[ch], channel, sfbwidth_table[sfreqi].s); + +# if !defined(OPT_STRICT) + /* + * According to ISO/IEC 11172-3, "Alias reduction is not applied for + * granules with block_type == 2 (short block)." However, other + * sources suggest alias reduction should indeed be performed on the + * lower two subbands of mixed blocks. Most other implementations do + * this, so by default we will too. + */ + if (channel->flags & mixed_block_flag) + III_aliasreduce(xr[ch], 36); +# endif + } + else + III_aliasreduce(xr[ch], 576); + + l = 0; + + /* subbands 0-1 */ + + if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) { + unsigned int block_type; + + block_type = channel->block_type; + if (channel->flags & mixed_block_flag) + block_type = 0; + + /* long blocks */ + for (sb = 0; sb < 2; ++sb, l += 18) { + III_imdct_l(&xr[ch][l], output, block_type); + III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); + } + } + else { + /* short blocks */ + for (sb = 0; sb < 2; ++sb, l += 18) { + III_imdct_s(&xr[ch][l], output); + III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); + } + } + + III_freqinver(sample, 1); + + /* (nonzero) subbands 2-31 */ + + i = 576; + while (i > 36 && xr[ch][i - 1] == 0) + --i; + + sblimit = 32 - (576 - i) / 18; + + if (channel->block_type != 2) { + /* long blocks */ + for (sb = 2; sb < sblimit; ++sb, l += 18) { + III_imdct_l(&xr[ch][l], output, channel->block_type); + III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); + + if (sb & 1) + III_freqinver(sample, sb); + } + } + else { + /* short blocks */ + for (sb = 2; sb < sblimit; ++sb, l += 18) { + III_imdct_s(&xr[ch][l], output); + III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); + + if (sb & 1) + III_freqinver(sample, sb); + } + } + + /* remaining (zero) subbands */ + + for (sb = sblimit; sb < 32; ++sb) { + III_overlap_z((*frame->overlap)[ch][sb], sample, sb); + + if (sb & 1) + III_freqinver(sample, sb); + } + } + } + + return 0; +} + +/* + * NAME: layer->III() + * DESCRIPTION: decode a single Layer III frame + */ +int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame) +{ + struct mad_header *header = &frame->header; + unsigned int nch, priv_bitlen, next_md_begin = 0; + unsigned int si_len, data_bitlen, md_len; + unsigned int frame_space, frame_used, frame_free; + struct mad_bitptr ptr; + struct sideinfo si; + enum mad_error error; + int result = 0; + + /* allocate Layer III dynamic structures */ + + if (stream->main_data == 0) { + stream->main_data = malloc(MAD_BUFFER_MDLEN); + if (stream->main_data == 0) { + stream->error = MAD_ERROR_NOMEM; + return -1; + } + } + + if (frame->overlap == 0) { + frame->overlap = calloc(2 * 32 * 18, sizeof(mad_fixed_t)); + if (frame->overlap == 0) { + stream->error = MAD_ERROR_NOMEM; + return -1; + } + } + + nch = MAD_NCHANNELS(header); + si_len = (header->flags & MAD_FLAG_LSF_EXT) ? + (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32); + + /* check frame sanity */ + + if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) < + (signed int) si_len) { + stream->error = MAD_ERROR_BADFRAMELEN; + stream->md_len = 0; + return -1; + } + + /* check CRC word */ + + if (header->flags & MAD_FLAG_PROTECTION) { + header->crc_check = + mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check); + + if (header->crc_check != header->crc_target && + !(frame->options & MAD_OPTION_IGNORECRC)) { + stream->error = MAD_ERROR_BADCRC; + result = -1; + } + } + + /* decode frame side information */ + + error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT, + &si, &data_bitlen, &priv_bitlen); + if (error && result == 0) { + stream->error = error; + result = -1; + } + + header->flags |= priv_bitlen; + header->private_bits |= si.private_bits; + + /* find main_data of next frame */ + + { + struct mad_bitptr peek; + unsigned long header; + + mad_bit_init(&peek, stream->next_frame); + + header = mad_bit_read(&peek, 32); + if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) { + if (!(header & 0x00010000L)) /* protection_bit */ + mad_bit_skip(&peek, 16); /* crc_check */ + + next_md_begin = + mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8); + } + + mad_bit_finish(&peek); + } + + /* find main_data of this frame */ + + frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr); + + if (next_md_begin > si.main_data_begin + frame_space) + next_md_begin = 0; + + md_len = si.main_data_begin + frame_space - next_md_begin; + + frame_used = 0; + + if (si.main_data_begin == 0) { + ptr = stream->ptr; + stream->md_len = 0; + + frame_used = md_len; + } + else { + if (si.main_data_begin > stream->md_len) { + if (result == 0) { + stream->error = MAD_ERROR_BADDATAPTR; + result = -1; + } + } + else { + mad_bit_init(&ptr, + *stream->main_data + stream->md_len - si.main_data_begin); + + if (md_len > si.main_data_begin) { + assert(stream->md_len + md_len - + si.main_data_begin <= MAD_BUFFER_MDLEN); + + memcpy(*stream->main_data + stream->md_len, + mad_bit_nextbyte(&stream->ptr), + frame_used = md_len - si.main_data_begin); + stream->md_len += frame_used; + } + } + } + + frame_free = frame_space - frame_used; + + /* decode main_data */ + + if (result == 0) { + error = III_decode(&ptr, frame, &si, nch); + if (error) { + stream->error = error; + result = -1; + } + } + + /* designate ancillary bits */ + + stream->anc_ptr = ptr; + stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen; + +# if 0 && defined(DEBUG) + fprintf(stderr, + "main_data_begin:%u, md_len:%u, frame_free:%u, " + "data_bitlen:%u, anc_bitlen: %u\n", + si.main_data_begin, md_len, frame_free, + data_bitlen, stream->anc_bitlen); +# endif + + /* preload main_data buffer with up to 511 bytes for next frame(s) */ + + if (frame_free >= next_md_begin) { + memcpy(*stream->main_data, + stream->next_frame - next_md_begin, next_md_begin); + stream->md_len = next_md_begin; + } + else { + if (md_len < si.main_data_begin) { + unsigned int extra; + + extra = si.main_data_begin - md_len; + if (extra + frame_free > next_md_begin) + extra = next_md_begin - frame_free; + + if (extra < stream->md_len) { + memmove(*stream->main_data, + *stream->main_data + stream->md_len - extra, extra); + stream->md_len = extra; + } + } + else + stream->md_len = 0; + + memcpy(*stream->main_data + stream->md_len, + stream->next_frame - frame_free, frame_free); + stream->md_len += frame_free; + } + + return result; +} diff --git a/core/multimedia/opieplayer/libmad/layer3.h b/core/multimedia/opieplayer/libmad/layer3.h new file mode 100644 index 0000000..1fd83e2 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/layer3.h @@ -0,0 +1,30 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_LAYER3_H +# define LIBMAD_LAYER3_H + +# include "stream.h" +# include "frame.h" + +int mad_layer_III(struct mad_stream *, struct mad_frame *); + +# endif diff --git a/core/multimedia/opieplayer/libmad/libmad.pro b/core/multimedia/opieplayer/libmad/libmad.pro new file mode 100644 index 0000000..e3f75b7 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/libmad.pro @@ -0,0 +1,12 @@ +TEMPLATE = lib +CONFIG += qt warn_on release +HEADERS = libmad_version.h fixed.h bit.h timer.h stream.h frame.h synth.h decoder.h \ + layer12.h layer3.h huffman.h libmad_global.h mad.h libmadplugin.h libmadpluginimpl.h +SOURCES = version.c fixed.c bit.c timer.c stream.c frame.c synth.c decoder.c \ + layer12.c layer3.c huffman.c libmadplugin.cpp libmadpluginimpl.cpp +TARGET = madplugin +DESTDIR = ../../plugins/codecs +INCLUDEPATH += $(QPEDIR)/include .. +DEPENDPATH += ../$(QPEDIR)/include .. +LIBS += -lqpe -lm +VERSION = 1.0.0 diff --git a/core/multimedia/opieplayer/libmad/libmad_global.h b/core/multimedia/opieplayer/libmad/libmad_global.h new file mode 100644 index 0000000..f2a2a71 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/libmad_global.h @@ -0,0 +1,45 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_GLOBAL_H +# define LIBMAD_GLOBAL_H + +/* conditional debugging */ + +# if defined(DEBUG) && defined(NDEBUG) +# error "cannot define both DEBUG and NDEBUG" +# endif + +# if defined(DEBUG) +# include +# endif + +/* conditional features */ + +# if defined(OPT_SPEED) && defined(OPT_ACCURACY) +# error "cannot optimize for both speed and accuracy" +# endif + +# if defined(OPT_SPEED) && !defined(OPT_SSO) +# define OPT_SSO 1 +# endif + +# endif diff --git a/core/multimedia/opieplayer/libmad/libmad_version.h b/core/multimedia/opieplayer/libmad/libmad_version.h new file mode 100644 index 0000000..f8ee1fa --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/libmad_version.h @@ -0,0 +1,47 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_VERSION_H +# define LIBMAD_VERSION_H + +# define MAD_VERSION_MAJOR 0 +# define MAD_VERSION_MINOR 13 +# define MAD_VERSION_PATCH 0 +# define MAD_VERSION_EXTRA " (beta)" + +# define MAD_VERSION_STRINGIZE(str) #str +# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) + +# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_PATCH) \ + MAD_VERSION_EXTRA + +# define MAD_PUBLISHYEAR "2000-2001" +# define MAD_AUTHOR "Robert Leslie" +# define MAD_EMAIL "rob@mars.org" + +extern char const mad_version[]; +extern char const mad_copyright[]; +extern char const mad_author[]; +extern char const mad_build[]; + +# endif diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp new file mode 100644 index 0000000..b2b876f --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp @@ -0,0 +1,578 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define HAVE_MMAP + +#if defined(HAVE_MMAP) +# include +#endif +#include "libmadplugin.h" + + +extern "C" { +#include "mad.h" +} + + +#define MPEG_BUFFER_SIZE 65536 +//#define debugMsg(a) qDebug(a) +#define debugMsg(a) + + +class Input { +public: + char const *path; + int fd; +#if defined(HAVE_MMAP) + void *fdm; +#endif + unsigned char *data; + unsigned long length; + int eof; +}; + + +class Output { +public: + mad_fixed_t attenuate; + struct filter *filters; + unsigned int channels_in; + unsigned int channels_out; + unsigned int speed_in; + unsigned int speed_out; + const char *path; +}; + + +# if defined(HAVE_MMAP) +static void *map_file(int fd, unsigned long *length) +{ + void *fdm; + + *length += MAD_BUFFER_GUARD; + + fdm = mmap(0, *length, PROT_READ, MAP_SHARED, fd, 0); + if (fdm == MAP_FAILED) + return 0; + +# if defined(HAVE_MADVISE) + madvise(fdm, *length, MADV_SEQUENTIAL); +# endif + + return fdm; +} + + +static int unmap_file(void *fdm, unsigned long length) +{ + if (munmap(fdm, length) == -1) + return -1; + + return 0; +} +# endif + + +static inline QString tr( const char *str ) { + // Apparently this is okay from a plugin as it runs in the process space of the owner of the plugin + return qApp->translate( "MediaPlayer", str, "libmad strings for mp3 file info" ); +} + + +class LibMadPluginData { +public: + Input input; + Output output; + int bad_last_frame; + struct mad_stream stream; + struct mad_frame frame; + struct mad_synth synth; + bool flush; +}; + + +LibMadPlugin::LibMadPlugin() { + d = new LibMadPluginData; + d->input.fd = 0; +#if defined(HAVE_MMAP) + d->input.fdm = 0; +#endif + d->input.data = 0; + d->flush = TRUE; + info = tr( "No Song Open" ); +} + + +LibMadPlugin::~LibMadPlugin() { + close(); + delete d; +} + + +bool LibMadPlugin::isFileSupported( const QString& path ) { + debugMsg( "LibMadPlugin::isFileSupported" ); + + // Mpeg file extensions + // "mp2","mp3","m1v","m2v","m2s","mpg","vob","mpeg","ac3" + // Other media extensions + // "wav","mid","mod","s3m","ogg","avi","mov","sid" + + char *ext = strrchr( path.latin1(), '.' ); + + // Test file extension + if ( ext ) { + if ( strncasecmp(ext, ".mp2", 4) == 0 ) + return TRUE; + if ( strncasecmp(ext, ".mp3", 4) == 0 ) + return TRUE; + } + + return FALSE; +} + + +bool LibMadPlugin::open( const QString& path ) { + debugMsg( "LibMadPlugin::open" ); + + d->bad_last_frame = 0; + d->flush = TRUE; + info = QString( "" ); + + //qDebug( "Opening %s", path.latin1() ); + + d->input.path = path.latin1(); + d->input.fd = ::open( d->input.path, O_RDONLY ); + if (d->input.fd == -1) { + qDebug("error opening %s", d->input.path ); + return FALSE; + } + + printID3Tags(); + +#if defined(HAVE_MMAP) + struct stat stat; + if (fstat(d->input.fd, &stat) == -1) { + qDebug("error calling fstat"); return FALSE; + } + if (S_ISREG(stat.st_mode) && stat.st_size > 0) { + d->input.length = stat.st_size; + d->input.fdm = map_file(d->input.fd, &d->input.length); + if (d->input.fdm == 0) { + qDebug("error mmapping file"); return FALSE; + } + d->input.data = (unsigned char *)d->input.fdm; + } +#endif + + if (d->input.data == 0) { + d->input.data = (unsigned char *)malloc(MPEG_BUFFER_SIZE); + if (d->input.data == 0) { + qDebug("error allocating input buffer"); + return FALSE; + } + d->input.length = 0; + } + + d->input.eof = 0; + + mad_stream_init(&d->stream); + mad_frame_init(&d->frame); + mad_synth_init(&d->synth); + + return TRUE; +} + + +bool LibMadPlugin::close() { + debugMsg( "LibMadPlugin::close" ); + + int result = TRUE; + + mad_synth_finish(&d->synth); + mad_frame_finish(&d->frame); + mad_stream_finish(&d->stream); + +#if defined(HAVE_MMAP) + if (d->input.fdm) { + if (unmap_file(d->input.fdm, d->input.length) == -1) { + qDebug("error munmapping file"); + result = FALSE; + } + d->input.fdm = 0; + d->input.data = 0; + } +#endif + + if (d->input.data) { + free(d->input.data); + d->input.data = 0; + } + + if (::close(d->input.fd) == -1) { + qDebug("error closing file %s", d->input.path); + result = FALSE; + } + + d->input.fd = 0; + + return result; +} + + +bool LibMadPlugin::isOpen() { + debugMsg( "LibMadPlugin::isOpen" ); + return ( d->input.fd != 0 ); +} + + +int LibMadPlugin::audioStreams() { + debugMsg( "LibMadPlugin::audioStreams" ); + return 1; +} + + +int LibMadPlugin::audioChannels( int ) { + debugMsg( "LibMadPlugin::audioChannels" ); +/* + long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); + qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 ); + return d->frame.header.mode > 0 ? 2 : 1; +*/ + return 2; +} + + +int LibMadPlugin::audioFrequency( int ) { + debugMsg( "LibMadPlugin::audioFrequency" ); + long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); + qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate ); + return d->frame.header.samplerate; +} + + +int LibMadPlugin::audioSamples( int ) { + debugMsg( "LibMadPlugin::audioSamples" ); +/* + long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); + mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream ); + qDebug( "LibMadPlugin::audioSamples: %i*%i", d->frame.header.duration.seconds, d->frame.header.samplerate ); + return d->frame.header.duration.seconds * d->frame.header.samplerate; +*/ + return 10000000; +} + + +bool LibMadPlugin::audioSetSample( long, int ) { + debugMsg( "LibMadPlugin::audioSetSample" ); + return FALSE; +} + + +long LibMadPlugin::audioGetSample( int ) { + debugMsg( "LibMadPlugin::audioGetSample" ); + return 0; +} + +/* +bool LibMadPlugin::audioReadSamples( short *, int, long, int ) { + debugMsg( "LibMadPlugin::audioReadSamples" ); + return FALSE; +} + + +bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) { + debugMsg( "LibMadPlugin::audioReReadSamples" ); + return FALSE; +} +*/ + +bool LibMadPlugin::read() { + debugMsg( "LibMadPlugin::read" ); + int len; + + if (d->input.eof) + return FALSE; + +#if defined(HAVE_MMAP) + if (d->input.fdm) { + unsigned long skip = 0; + + if (d->stream.next_frame) { + struct stat stat; + + if (fstat(d->input.fd, &stat) == -1) + return FALSE; + + if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length) + return FALSE; + + // file size changed; update memory map + skip = d->stream.next_frame - d->input.data; + + if (unmap_file(d->input.fdm, d->input.length) == -1) { + d->input.fdm = 0; + d->input.data = 0; + return FALSE; + } + + d->input.length = stat.st_size; + + d->input.fdm = map_file(d->input.fd, &d->input.length); + if (d->input.fdm == 0) { + d->input.data = 0; + return FALSE; + } + + d->input.data = (unsigned char *)d->input.fdm; + } + + mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip); + + } else +#endif + { + if (d->stream.next_frame) { + memmove(d->input.data, d->stream.next_frame, + d->input.length = &d->input.data[d->input.length] - d->stream.next_frame); + } + + do { + len = ::read(d->input.fd, d->input.data + d->input.length, MPEG_BUFFER_SIZE - d->input.length); + } + while (len == -1 && errno == EINTR); + + if (len == -1) { + qDebug("error reading audio"); + return FALSE; + } + else if (len == 0) { + d->input.eof = 1; + + assert(MPEG_BUFFER_SIZE - d->input.length >= MAD_BUFFER_GUARD); + + while (len < MAD_BUFFER_GUARD) + d->input.data[d->input.length + len++] = 0; + } + + mad_stream_buffer(&d->stream, d->input.data, d->input.length += len); + } + + return TRUE; +} + + +static mad_fixed_t left_err, right_err; +static const int bits = 16; +static const int shift = MAD_F_FRACBITS + 1 - bits; + + +inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error ) +{ + sample += error; + mad_fixed_t quantized = (sample >= MAD_F_ONE) ? MAD_F_ONE - 1 : ( (sample < -MAD_F_ONE) ? -MAD_F_ONE : sample ); + quantized &= ~((1L << shift) - 1); + error = sample - quantized; + return quantized >> shift; +} + + +inline void audio_pcm( short *data, unsigned int nsamples, mad_fixed_t *left, mad_fixed_t *right ) +{ + if ( right ) { + while (nsamples--) { + data[0] = audio_linear_dither( *left++, left_err ); + data[1] = audio_linear_dither( *right++, right_err ); + data += 2; + } + } else { + while (nsamples--) { + data[0] = data[1] = audio_linear_dither( *left++, left_err ); + data += 2; + } + } +} + + +bool LibMadPlugin::decode( short *output, long samples, long& samplesMade ) { + debugMsg( "LibMadPlugin::decode" ); + + static int buffered = 0; + static mad_fixed_t buffer[2][65536 * 2]; + int offset = buffered; + samplesMade = 0; + + static int maxBuffered = 8000; // 65536; + + if ( samples > maxBuffered ) + samples = maxBuffered; + + if ( d->flush ) { + buffered = 0; + offset = 0; + d->flush = FALSE; + } + + while ( buffered < maxBuffered ) { + + while (mad_frame_decode(&d->frame, &d->stream) == -1) { + if (!MAD_RECOVERABLE(d->stream.error)) { + debugMsg( "feed me" ); + return FALSE; // Feed me + } + if ( d->stream.error == MAD_ERROR_BADCRC ) { + mad_frame_mute(&d->frame); + qDebug( "error decoding, bad crc" ); + } + } + + mad_synth_frame(&d->synth, &d->frame); + int decodedSamples = d->synth.pcm.length; + memcpy( &(buffer[0][offset]), d->synth.pcm.samples[0], decodedSamples * sizeof(mad_fixed_t) ); + if ( d->synth.pcm.channels == 2 ) + memcpy( &(buffer[1][offset]), d->synth.pcm.samples[1], decodedSamples * sizeof(mad_fixed_t) ); + offset += decodedSamples; + buffered += decodedSamples; + } + + audio_pcm( output, samples, buffer[0], (d->synth.pcm.channels == 2) ? buffer[1] : 0 ); +// audio_pcm( output, samples, buffer[1], buffer[0] ); +// audio_pcm( output, samples, buffer[0], buffer[1] ); + samplesMade = samples; + memmove( buffer[0], &(buffer[0][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); + if ( d->synth.pcm.channels == 2 ) + memmove( buffer[1], &(buffer[1][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); + buffered -= samples; + + return TRUE; +} + +/* +bool LibMadPlugin::audioReadMonoSamples( short *, long, long&, int ) { + debugMsg( "LibMadPlugin::audioReadMonoSamples" ); + return FALSE; +} + + +bool LibMadPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) { +*/ +bool LibMadPlugin::audioReadSamples( short *output, int /*channels*/, long samples, long& samplesMade, int ) { + debugMsg( "LibMadPlugin::audioReadStereoSamples" ); + + static bool needInput = TRUE; + + if ( samples == 0 ) + return TRUE; + + do { + if ( needInput ) + if ( !read() ) { +// if ( d->input.eof ) +// needInput = FALSE; +// else + return TRUE; + } + + needInput = FALSE; + + if ( decode( output, samples, samplesMade ) ) + return FALSE; + else + needInput = TRUE; + } + while ( ( samplesMade < samples ) && ( !d->input.eof ) ); +/* + static bool firstTimeThru = TRUE; + + if ( firstTimeThru ) { + firstTimeThru = FALSE; + decode( output, samples, samplesMade ); + return FALSE; + } else +*/ + return TRUE; +} + + +double LibMadPlugin::getTime() { + debugMsg( "LibMadPlugin::getTime" ); + return 0.0; +} + + +void LibMadPlugin::printID3Tags() { + debugMsg( "LibMadPlugin::printID3Tags" ); + + char id3v1[128 + 1]; + + if ( ::lseek( d->input.fd, -128, SEEK_END ) == -1 ) { + qDebug( "error seeking to id3 tags" ); + return; + } + + if ( ::read( d->input.fd, id3v1, 128 ) != 128 ) { + qDebug( "error reading in id3 tags" ); + return; + } + + if ( ::strncmp( (const char *)id3v1, "TAG", 3 ) != 0 ) { + debugMsg( "sorry, no id3 tags" ); + } else { + int len[5] = { 30, 30, 30, 4, 30 }; + QString label[5] = { tr( "Title" ), tr( "Artist" ), tr( "Album" ), tr( "Year" ), tr( "Comment" ) }; + char *ptr = id3v1 + 3, *ptr2 = ptr + len[0]; + qDebug( "ID3 tags in file:" ); + info = ""; + for ( int i = 0; i < 5; ptr += len[i], i++, ptr2 += len[i] ) { + char push = *ptr2; + *ptr2 = '\0'; + char *ptr3 = ptr2; + while ( ptr3-1 >= ptr && isspace(ptr3[-1]) ) ptr3--; + char push2 = *ptr3; *ptr3 = '\0'; + if ( strcmp( ptr, "" ) ) + info += ( i != 0 ? ", " : "" ) + label[i] + ": " + ptr; + //qDebug( info.latin1() ); + *ptr3 = push2; + *ptr2 = push; + } + if (id3v1[126] == 0 && id3v1[127] != 0) + info += tr( ", Track: " ) + id3v1[127]; + } + + if ( ::lseek(d->input.fd, 0, SEEK_SET) == -1 ) { + qDebug( "error seeking back to beginning" ); + return; + } +} + diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.h b/core/multimedia/opieplayer/libmad/libmadplugin.h new file mode 100644 index 0000000..88647ae --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/libmadplugin.h @@ -0,0 +1,101 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LIBMAD_PLUGIN_H +#define LIBMAD_PLUGIN_H + + +#include +#include "mediaplayerplugininterface.h" + + +class LibMadPluginData; + + +class LibMadPlugin : public MediaPlayerDecoder { + +public: + LibMadPlugin(); + ~LibMadPlugin(); + + const char *pluginName() { return "LibMadPlugin"; } + const char *pluginComment() { return "This is the libmad library that has been wrapped as a plugin"; } + double pluginVersion() { return 1.0; } + + bool isFileSupported( const QString& ); + bool open( const QString& ); + bool close(); + bool isOpen(); + const QString &fileInfo() { return info; } + + // If decoder doesn't support audio then return 0 here + int audioStreams(); + int audioChannels( int stream ); + int audioFrequency( int stream ); + int audioSamples( int stream ); + bool audioSetSample( long sample, int stream ); + long audioGetSample( int stream ); +// bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ); +// bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ); + bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ); +// bool audioReadSamples( short *output, int channel, long samples, int stream ); +// bool audioReReadSamples( short *output, int channel, long samples, int stream ); + + + bool read(); + bool decode( short *output, long samples, long& samplesRead ); + void printID3Tags(); + + + // If decoder doesn't support video then return 0 here + int videoStreams() { return 0; } + int videoWidth( int ) { return 0; } + int videoHeight( int ) { return 0; } + double videoFrameRate( int ) { return 0.0; } + int videoFrames( int ) { return 0; } + bool videoSetFrame( long, int ) { return FALSE; } + long videoGetFrame( int ) { return 0; } + bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; } + bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; } + bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; } + + // Profiling + double getTime(); + + // Ignore if these aren't supported + bool setSMP( int ) { return FALSE; } + bool setMMX( bool ) { return FALSE; } + + // Capabilities + bool supportsAudio() { return TRUE; } + bool supportsVideo() { return FALSE; } + bool supportsYUV() { return FALSE; } + bool supportsMMX() { return TRUE; } + bool supportsSMP() { return FALSE; } + bool supportsStereo() { return TRUE; } + bool supportsScaling() { return FALSE; } + +private: + LibMadPluginData *d; + QString info; + +}; + + +#endif diff --git a/core/multimedia/opieplayer/libmad/libmadpluginimpl.cpp b/core/multimedia/opieplayer/libmad/libmadpluginimpl.cpp new file mode 100644 index 0000000..028c658 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/libmadpluginimpl.cpp @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "libmadplugin.h" +#include "libmadpluginimpl.h" + + +LibMadPluginImpl::LibMadPluginImpl() + : libmadplugin(0), ref(0) +{ +} + + +LibMadPluginImpl::~LibMadPluginImpl() +{ + if ( libmadplugin ) + delete libmadplugin; +} + + +MediaPlayerDecoder *LibMadPluginImpl::decoder() +{ + if ( !libmadplugin ) + libmadplugin = new LibMadPlugin; + return libmadplugin; +} + + +MediaPlayerEncoder *LibMadPluginImpl::encoder() +{ + return NULL; +} + + +#ifndef QT_NO_COMPONENT + + +QRESULT LibMadPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) ) + *iface = this, (*iface)->addRef(); + return QS_OK; +} + + +Q_EXPORT_INTERFACE() +{ + Q_CREATE_INSTANCE( LibMadPluginImpl ) +} + + +#endif + diff --git a/core/multimedia/opieplayer/libmad/libmadpluginimpl.h b/core/multimedia/opieplayer/libmad/libmadpluginimpl.h new file mode 100644 index 0000000..a26b421 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/libmadpluginimpl.h @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LIBMAD_PLUGIN_IMPL_H +#define LIBMAD_PLUGIN_IMPL_H + + +#include "../mediaplayerplugininterface.h" + + +class LibMadPlugin; + + +class LibMadPluginImpl : public MediaPlayerPluginInterface +{ +public: + LibMadPluginImpl(); + virtual ~LibMadPluginImpl(); + +#ifndef QT_NO_COMPONENT + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT + +#endif + + virtual MediaPlayerDecoder *decoder(); + virtual MediaPlayerEncoder *encoder(); + +private: + LibMadPlugin *libmadplugin; + ulong ref; +}; + + +#endif + diff --git a/core/multimedia/opieplayer/libmad/mad.h b/core/multimedia/opieplayer/libmad/mad.h new file mode 100644 index 0000000..9db9da3 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/mad.h @@ -0,0 +1,830 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * If you would like to negotiate alternate licensing terms, you may do + * so by contacting the author: Robert Leslie + */ + +# define SIZEOF_INT 4 +# define SIZEOF_LONG 4 +# define SIZEOF_LONG_LONG 8 + +/* Id: version.h,v 1.16 2001/04/05 04:57:11 rob Exp */ + +# ifndef LIBMAD_VERSION_H +# define LIBMAD_VERSION_H + +# define MAD_VERSION_MAJOR 0 +# define MAD_VERSION_MINOR 13 +# define MAD_VERSION_PATCH 0 +# define MAD_VERSION_EXTRA " (beta)" + +# define MAD_VERSION_STRINGIZE(str) #str +# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) + +# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_PATCH) \ + MAD_VERSION_EXTRA + +# define MAD_PUBLISHYEAR "2000-2001" +# define MAD_AUTHOR "Robert Leslie" +# define MAD_EMAIL "rob@mars.org" + +extern char const mad_version[]; +extern char const mad_copyright[]; +extern char const mad_author[]; +extern char const mad_build[]; + +# endif + +/* Id: fixed.h,v 1.23 2001/04/05 04:57:11 rob Exp */ + +# ifndef LIBMAD_FIXED_H +# define LIBMAD_FIXED_H + +# if SIZEOF_INT >= 4 +typedef signed int mad_fixed_t; + +typedef signed int mad_fixed64hi_t; +typedef unsigned int mad_fixed64lo_t; +# else +typedef signed long mad_fixed_t; + +typedef signed long mad_fixed64hi_t; +typedef unsigned long mad_fixed64lo_t; +# endif + +/* + * Fixed-point format: 0xABBBBBBB + * A == whole part (sign + 3 bits) + * B == fractional part (28 bits) + * + * Values are signed two's complement, so the effective range is: + * 0x80000000 to 0x7fffffff + * -8.0 to +7.9999999962747097015380859375 + * + * The smallest representable value is: + * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) + * + * 28 bits of fractional accuracy represent about + * 8.6 digits of decimal accuracy. + * + * Fixed-point numbers can be added or subtracted as normal + * integers, but multiplication requires shifting the 64-bit result + * from 56 fractional bits back to 28 (and rounding.) + * + * Changing the definition of MAD_F_FRACBITS is only partially + * supported, and must be done with care. + */ + +# define MAD_F_FRACBITS 28 + +# if MAD_F_FRACBITS == 28 +# define MAD_F(x) ((mad_fixed_t) (x##L)) +# else +# if MAD_F_FRACBITS < 28 +# warning "MAD_F_FRACBITS < 28" +# define MAD_F(x) ((mad_fixed_t) \ + (((x##L) + \ + (1L << (28 - MAD_F_FRACBITS - 1))) >> \ + (28 - MAD_F_FRACBITS))) +# elif MAD_F_FRACBITS > 28 +# error "MAD_F_FRACBITS > 28 not currently supported" +# define MAD_F(x) ((mad_fixed_t) \ + ((x##L) << (MAD_F_FRACBITS - 28))) +# endif +# endif + +# define MAD_F_MIN ((mad_fixed_t) -0x80000000L) +# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL) + +# define MAD_F_ONE MAD_F(0x10000000) + +# define mad_f_tofixed(x) ((mad_fixed_t) \ + ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5)) +# define mad_f_todouble(x) ((double) \ + ((x) / (double) (1L << MAD_F_FRACBITS))) + +# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) +# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) + /* (x should be positive) */ + +# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) + +# define mad_f_add(x, y) ((x) + (y)) +# define mad_f_sub(x, y) ((x) - (y)) + +# if defined(FPM_64BIT) + +/* + * This version should be the most accurate if 64-bit (long long) types are + * supported by the compiler, although it may not be the most efficient. + */ +# if defined(OPT_ACCURACY) +# define mad_f_mul(x, y) \ + ((mad_fixed_t) \ + ((((signed long long) (x) * (y)) + \ + (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS)) +# else +# define mad_f_mul(x, y) \ + ((mad_fixed_t) (((signed long long) (x) * (y)) >> MAD_F_SCALEBITS)) +# endif + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- Intel --------------------------------------------------------------- */ + +# elif defined(FPM_INTEL) + +/* + * This Intel version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("imull %3" \ + : "=a" (lo), "=d" (hi) \ + : "%a" (x), "rm" (y) \ + : "cc") + +# if defined(OPT_ACCURACY) +/* + * This gives best accuracy but is not very fast. + */ +# define MAD_F_MLA(hi, lo, x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + asm ("addl %2,%0\n\t" \ + "adcl %3,%1" \ + : "=rm" (lo), "=rm" (hi) \ + : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \ + : "cc"); \ + }) +# endif /* OPT_ACCURACY */ + +# if defined(OPT_ACCURACY) +/* + * Surprisingly, this is faster than SHRD followed by ADC. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed64hi_t __hi_; \ + mad_fixed64lo_t __lo_; \ + mad_fixed_t __result; \ + asm ("addl %4,%2\n\t" \ + "adcl %5,%3" \ + : "=rm" (__lo_), "=rm" (__hi_) \ + : "0" (lo), "1" (hi), \ + "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \ + : "cc"); \ + asm ("shrdl %3,%2,%1" \ + : "=rm" (__result) \ + : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# else +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("shrdl %3,%2,%1" \ + : "=rm" (__result) \ + : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# endif /* OPT_ACCURACY */ + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- ARM ----------------------------------------------------------------- */ + +# elif defined(FPM_ARM) + +/* + * This ARM V4 version is as accurate as FPM_64BIT but much faster. The + * least significant bit is properly rounded at no CPU cycle cost! + */ +# if 1 +/* + * There's a bug somewhere, possibly in the compiler, that sometimes makes + * this necessary instead of the default implementation via MAD_F_MLX and + * mad_f_scale64. It may be related to the use (or lack) of + * -finline-functions and/or -fstrength-reduce. + * + * This is also apparently faster than MAD_F_MLX/mad_f_scale64. + */ +# define mad_f_mul(x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + mad_fixed_t __result; \ + asm ("smull %0, %1, %3, %4\n\t" \ + "movs %0, %0, lsr %5\n\t" \ + "adc %2, %0, %1, lsl %6" \ + : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ + : "%r" (x), "r" (y), \ + "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# endif + +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("smull %0, %1, %2, %3" \ + : "=&r" (lo), "=&r" (hi) \ + : "%r" (x), "r" (y)) + +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("smlal %0, %1, %2, %3" \ + : "+r" (lo), "+r" (hi) \ + : "%r" (x), "r" (y)) + +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("movs %0, %1, lsr %3\n\t" \ + "adc %0, %0, %2, lsl %4" \ + : "=r" (__result) \ + : "r" (lo), "r" (hi), \ + "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- MIPS ---------------------------------------------------------------- */ + +# elif defined(FPM_MIPS) + +/* + * This MIPS version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("mult %2,%3" \ + : "=l" (lo), "=h" (hi) \ + : "%r" (x), "r" (y)) + +# if defined(HAVE_MADD_ASM) +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("madd %2,%3" \ + : "+l" (lo), "+h" (hi) \ + : "%r" (x), "r" (y)) +# elif defined(HAVE_MADD16_ASM) +/* + * This loses significant accuracy due to the 16-bit integer limit in the + * multiply/accumulate instruction. + */ +# define MAD_F_ML0(hi, lo, x, y) \ + asm ("mult %2,%3" \ + : "=l" (lo), "=h" (hi) \ + : "%r" ((x) >> 12), "r" ((y) >> 16)) +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("madd16 %2,%3" \ + : "+l" (lo), "+h" (hi) \ + : "%r" ((x) >> 12), "r" ((y) >> 16)) +# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) +# endif + +# if defined(OPT_SPEED) +# define mad_f_scale64(hi, lo) \ + ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS))) +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* --- SPARC --------------------------------------------------------------- */ + +# elif defined(FPM_SPARC) + +/* + * This SPARC V8 version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("smul %2, %3, %0\n\t" \ + "rd %%y, %1" \ + : "=r" (lo), "=r" (hi) \ + : "%r" (x), "rI" (y)) + +/* --- PowerPC ------------------------------------------------------------- */ + +# elif defined(FPM_PPC) + +/* + * This PowerPC version is tuned for the 4xx embedded processors. It is + * effectively a tuned version of FPM_64BIT. It is a little faster and just + * as accurate. The disposition of the least significant bit depends on + * OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("mulhw %1, %2, %3\n\t" \ + "mullw %0, %2, %3" \ + : "=&r" (lo), "=&r" (hi) \ + : "%r" (x), "r" (y)) + +# define MAD_F_MLA(hi, lo, x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + asm ("addc %0, %2, %3\n\t" \ + "adde %1, %4, %5" \ + : "=r" (lo), "=r" (hi) \ + : "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \ + }) + +# if defined(OPT_ACCURACY) +/* + * This is accurate and ~2 - 2.5 times slower than the unrounded version. + * + * The __volatile__ improves the generated code by another 5% (fewer spills + * to memory); eventually they should be removed. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + mad_fixed64hi_t __hi_; \ + mad_fixed64lo_t __lo_; \ + asm __volatile__ ("addc %0, %2, %4\n\t" \ + "addze %1, %3" \ + : "=r" (__lo_), "=r" (__hi_) \ + : "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \ + asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \ + "rlwimi %0, %1,32-%3,%3,31" \ + : "=&r" (__result) \ + : "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \ + __result; \ + }) +# else +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \ + "rlwimi %0, %1,32-%3,%3,31" \ + : "=r" (__result) \ + : "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \ + __result; \ + }) +# endif /* OPT_ACCURACY */ + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- Default ------------------------------------------------------------- */ + +# elif defined(FPM_DEFAULT) + +/* + * This version is the most portable but it loses significant accuracy. + * Furthermore, accuracy is biased against the second argument, so care + * should be taken when ordering operands. + * + * The scale factors are constant as this is not used with SSO. + * + * Pre-rounding is required to stay within the limits of compliance. + */ +# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ + (((y) + (1L << 15)) >> 16)) + +/* ------------------------------------------------------------------------- */ + +# else +# error "no FPM selected" +# endif + +/* default implementations */ + +# if !defined(mad_f_mul) +# define mad_f_mul(x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + mad_f_scale64(__hi, __lo); \ + }) +# endif + +# if !defined(MAD_F_MLA) +# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y))) +# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y))) +# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) +# endif + +# if !defined(MAD_F_ML0) +# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y)) +# endif + +# if !defined(MAD_F_MLZ) +# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo)) +# endif + +# if !defined(mad_f_scale64) +# if defined(OPT_ACCURACY) +# define mad_f_scale64(hi, lo) \ + ((((mad_fixed_t) \ + (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \ + ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1) +# else +# define mad_f_scale64(hi, lo) \ + ((mad_fixed_t) \ + (((hi) << (32 - MAD_F_SCALEBITS)) | \ + ((lo) >> MAD_F_SCALEBITS))) +# endif +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* miscellaneous C routines */ + +mad_fixed_t mad_f_abs(mad_fixed_t); + +# endif + +/* Id: bit.h,v 1.7 2001/04/05 04:57:11 rob Exp */ + +# ifndef LIBMAD_BIT_H +# define LIBMAD_BIT_H + +struct mad_bitptr { + unsigned char const *byte; + unsigned short cache; + unsigned short left; +}; + +void mad_bit_init(struct mad_bitptr *, unsigned char const *); + +# define mad_bit_finish(bitptr) /* nothing */ + +unsigned int mad_bit_length(struct mad_bitptr const *, + struct mad_bitptr const *); + +# define mad_bit_bitsleft(bitptr) ((bitptr)->left) +unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); + +void mad_bit_skip(struct mad_bitptr *, unsigned int); +unsigned long mad_bit_read(struct mad_bitptr *, unsigned int); +void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long); + +unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); + +# endif + +/* Id: timer.h,v 1.10 2001/04/05 04:57:11 rob Exp */ + +# ifndef LIBMAD_TIMER_H +# define LIBMAD_TIMER_H + +typedef struct { + signed long seconds; /* whole seconds */ + unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ +} mad_timer_t; + +extern mad_timer_t const mad_timer_zero; + +# define MAD_TIMER_RESOLUTION 352800000UL + +enum mad_units { + MAD_UNITS_HOURS = -2, + MAD_UNITS_MINUTES = -1, + MAD_UNITS_SECONDS = 0, + + /* metric units */ + + MAD_UNITS_DECISECONDS = 10, + MAD_UNITS_CENTISECONDS = 100, + MAD_UNITS_MILLISECONDS = 1000, + + /* audio sample units */ + + MAD_UNITS_8000_HZ = 8000, + MAD_UNITS_11025_HZ = 11025, + MAD_UNITS_12000_HZ = 12000, + + MAD_UNITS_16000_HZ = 16000, + MAD_UNITS_22050_HZ = 22050, + MAD_UNITS_24000_HZ = 24000, + + MAD_UNITS_32000_HZ = 32000, + MAD_UNITS_44100_HZ = 44100, + MAD_UNITS_48000_HZ = 48000, + + /* video frame/field units */ + + MAD_UNITS_24_FPS = 24, + MAD_UNITS_25_FPS = 25, + MAD_UNITS_30_FPS = 30, + MAD_UNITS_48_FPS = 48, + MAD_UNITS_50_FPS = 50, + MAD_UNITS_60_FPS = 60, + + /* CD audio frames */ + + MAD_UNITS_75_FPS = 75, + + /* video drop-frame units */ + + MAD_UNITS_23_976_FPS = -24, + MAD_UNITS_24_975_FPS = -25, + MAD_UNITS_29_97_FPS = -30, + MAD_UNITS_47_952_FPS = -48, + MAD_UNITS_49_95_FPS = -50, + MAD_UNITS_59_94_FPS = -60 +}; + +# define mad_timer_reset(timer) (*(timer) = mad_timer_zero) + +int mad_timer_compare(mad_timer_t, mad_timer_t); + +# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero) + +void mad_timer_negate(mad_timer_t *); +mad_timer_t mad_timer_abs(mad_timer_t); + +void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long); +void mad_timer_add(mad_timer_t *, mad_timer_t); +void mad_timer_multiply(mad_timer_t *, signed long); + +signed long mad_timer_count(mad_timer_t, enum mad_units); +unsigned long mad_timer_fraction(mad_timer_t, unsigned long); +void mad_timer_string(mad_timer_t, char *, char const *, + enum mad_units, enum mad_units, unsigned long); + +# endif + +/* Id: stream.h,v 1.12 2001/04/10 05:18:21 rob Exp */ + +# ifndef LIBMAD_STREAM_H +# define LIBMAD_STREAM_H + +# define MAD_BUFFER_GUARD 8 +# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) + +enum mad_error { + MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ + MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ + + MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ + + MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ + MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ + MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ + MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ + MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ + + MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ + MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ + MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ + MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ + MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ + MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ + MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ + MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ + MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ + MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ + MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ + MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ +}; + +# define MAD_RECOVERABLE(error) ((error) & 0xff00) + +struct mad_stream { + unsigned char const *buffer; /* input bitstream buffer */ + unsigned char const *bufend; /* end of buffer */ + unsigned long skiplen; /* bytes to skip before next frame */ + + int sync; /* stream sync found */ + unsigned long freerate; /* free bitrate (fixed) */ + + unsigned char const *this_frame; /* start of current frame */ + unsigned char const *next_frame; /* start of next frame */ + struct mad_bitptr ptr; /* current processing bit pointer */ + + struct mad_bitptr anc_ptr; /* ancillary bits pointer */ + unsigned int anc_bitlen; /* number of ancillary bits */ + + unsigned char (*main_data)[MAD_BUFFER_MDLEN]; + /* Layer III main_data() */ + unsigned int md_len; /* bytes in main_data */ + + int options; /* decoding options (see below) */ + enum mad_error error; /* error code (see above) */ +}; + +enum { + MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ + MAD_OPTION_HALFSAMPLERATE = 0x0002, /* generate PCM at 1/2 sample rate */ +# if 0 /* not yet implemented */ + MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ + MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ + MAD_OPTION_SINGLECHANNEL = 0x0030, /* combine channels */ +# endif +}; + +void mad_stream_init(struct mad_stream *); +void mad_stream_finish(struct mad_stream *); + +# define mad_stream_options(stream, opts) ((stream)->options = (opts)) + +void mad_stream_buffer(struct mad_stream *, + unsigned char const *, unsigned long); +void mad_stream_skip(struct mad_stream *, unsigned long); + +int mad_stream_sync(struct mad_stream *); + +# endif + +/* Id: frame.h,v 1.13 2001/04/05 04:57:11 rob Exp */ + +# ifndef LIBMAD_FRAME_H +# define LIBMAD_FRAME_H + +enum mad_layer { + MAD_LAYER_I = 1, /* Layer I */ + MAD_LAYER_II = 2, /* Layer II */ + MAD_LAYER_III = 3 /* Layer III */ +}; + +enum mad_mode { + MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ + MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ + MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ + MAD_MODE_STEREO = 3 /* normal LR stereo */ +}; + +enum mad_emphasis { + MAD_EMPHASIS_NONE = 0, /* no emphasis */ + MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ + MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */ +}; + +struct mad_frame { + struct mad_header { + enum mad_layer layer; /* audio layer (1, 2, or 3) */ + enum mad_mode mode; /* channel mode (see above) */ + int mode_extension; /* additional mode info */ + enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ + + unsigned long bitrate; /* stream bitrate (bps) */ + unsigned int samplerate; /* sampling frequency (Hz) */ + + unsigned short crc_check; /* frame CRC accumulator */ + unsigned short crc_target; /* final target CRC checksum */ + + int flags; /* flags (see below) */ + int private_bits; /* private bits (see below) */ + + mad_timer_t duration; /* audio playing time of frame */ + } header; + + int options; /* decoding options (from stream) */ + + mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ + mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */ +}; + +# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) +# define MAD_NSBSAMPLES(header) \ + ((header)->layer == MAD_LAYER_I ? 12 : \ + (((header)->layer == MAD_LAYER_III && \ + ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) + +enum { + MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ + MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ + + MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ + MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ + MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ + MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ + + MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ + MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ + MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ + + MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ + MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ + MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ +}; + +enum { + MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ + MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ +}; + +void mad_header_init(struct mad_header *); + +# define mad_header_finish(header) /* nothing */ + +int mad_header_decode(struct mad_header *, struct mad_stream *); + +void mad_frame_init(struct mad_frame *); +void mad_frame_finish(struct mad_frame *); + +int mad_frame_decode(struct mad_frame *, struct mad_stream *); + +void mad_frame_mute(struct mad_frame *); + +# endif + +/* Id: synth.h,v 1.8 2001/04/05 04:57:11 rob Exp */ + +# ifndef LIBMAD_SYNTH_H +# define LIBMAD_SYNTH_H + +struct mad_synth { + mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ + /* [ch][eo][peo][s][v] */ + + unsigned int phase; /* current processing phase */ + + struct mad_pcm { + unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short channels; /* number of channels */ + unsigned short length; /* number of samples per channel */ + mad_fixed_t samples[2][1152]; /* PCM output samples */ + } pcm; +}; + +void mad_synth_init(struct mad_synth *); + +# define mad_synth_finish(synth) /* nothing */ + +void mad_synth_mute(struct mad_synth *); + +void mad_synth_frame(struct mad_synth *, struct mad_frame const *); + +# endif + +/* Id: decoder.h,v 1.9 2001/04/05 04:57:11 rob Exp */ + +# ifndef LIBMAD_DECODER_H +# define LIBMAD_DECODER_H + +enum mad_decoder_mode { + MAD_DECODER_MODE_SYNC = 0, + MAD_DECODER_MODE_ASYNC +}; + +enum mad_flow { + MAD_FLOW_CONTINUE = 0x0000, + MAD_FLOW_STOP = 0x0010, + MAD_FLOW_BREAK = 0x0011, + MAD_FLOW_IGNORE = 0x0020 +}; + +struct mad_decoder { + enum mad_decoder_mode mode; + + int options; + + struct { + long pid; + int in; + int out; + } async; + + struct { + struct mad_stream stream; + struct mad_frame frame; + struct mad_synth synth; + } *sync; + + void *cb_data; + + enum mad_flow (*input_func)(void *, struct mad_stream *); + enum mad_flow (*header_func)(void *, struct mad_header const *); + enum mad_flow (*filter_func)(void *, struct mad_frame *); + enum mad_flow (*output_func)(void *, + struct mad_header const *, struct mad_pcm *); + enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); + enum mad_flow (*message_func)(void *, void *, unsigned int *); +}; + +void mad_decoder_init(struct mad_decoder *, void *, + enum mad_flow (*)(void *, struct mad_stream *), + enum mad_flow (*)(void *, struct mad_header const *), + enum mad_flow (*)(void *, struct mad_frame *), + enum mad_flow (*)(void *, + struct mad_header const *, + struct mad_pcm *), + enum mad_flow (*)(void *, + struct mad_stream *, + struct mad_frame *), + enum mad_flow (*)(void *, void *, unsigned int *)); +int mad_decoder_finish(struct mad_decoder *); + +# define mad_decoder_options(decoder, opts) ((decoder)->options = (opts)) + +int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); +int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); + +# endif + diff --git a/core/multimedia/opieplayer/libmad/qc_table.dat b/core/multimedia/opieplayer/libmad/qc_table.dat new file mode 100644 index 0000000..92b7f38 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/qc_table.dat @@ -0,0 +1,77 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +/* + * These are the Layer II classes of quantization. + * The table is derived from Table B.4 of ISO/IEC 11172-3. + */ + + { 3, 2, 5, + MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */, + MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, + { 5, 3, 7, + MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */, + MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, + { 7, 0, 3, + MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */, + MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ }, + { 9, 4, 10, + MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */, + MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, + { 15, 0, 4, + MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */, + MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ }, + { 31, 0, 5, + MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */, + MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ }, + { 63, 0, 6, + MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */, + MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ }, + { 127, 0, 7, + MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */, + MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ }, + { 255, 0, 8, + MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e 0.00000000024 */, + MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ }, + { 511, 0, 9, + MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e 0.00000000001 */, + MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ }, + { 1023, 0, 10, + MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e 0.00000000094 */, + MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ }, + { 2047, 0, 11, + MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e 0.00000000012 */, + MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ }, + { 4095, 0, 12, + MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e 0.00000000001 */, + MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ }, + { 8191, 0, 13, + MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e 0.00000000001 */, + MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ }, + { 16383, 0, 14, + MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */, + MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ }, + { 32767, 0, 15, + MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e 0.00000000093 */, + MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ }, + { 65535, 0, 16, + MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e 0.00000000023 */, + MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e 0.00000000000 */ } diff --git a/core/multimedia/opieplayer/libmad/qpe-libmadplugin.control b/core/multimedia/opieplayer/libmad/qpe-libmadplugin.control new file mode 100644 index 0000000..077350c --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/qpe-libmadplugin.control @@ -0,0 +1,9 @@ +Files: plugins/codecs/libmadplugin.so.1.0.0 plugins/codecs/libmadplugin.so.1.0 plugins/codecs/libmadplugin.so.1 plugins/codecs/libmadplugin.so +Priority: optional +Section: qpe/plugins +Maintainer: John Ryland +Architecture: arm +Version: $QPE_VERSION-3 +Depends: qpe-base ($QPE_VERSION) +Description: MP3 file plugin using libmad + Plugin to play MP3 files with the mediaplayer in the Qtopia environment. diff --git a/core/multimedia/opieplayer/libmad/rq_table.dat b/core/multimedia/opieplayer/libmad/rq_table.dat new file mode 100644 index 0000000..b6d1634 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/rq_table.dat @@ -0,0 +1,8747 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +/* + * This is the lookup table used to compute x^(4/3) for Layer III + * requantization. To maintain the best possible accuracy, the value is + * stored as a normalized mantissa with exponent. The requantization + * algorithm recombines these parts with appropriate scaling. + */ + + /* 0 */ { MAD_F(0x00000000) /* 0.000000000 */, 0 }, + /* 1 */ { MAD_F(0x04000000) /* 0.250000000 */, 2 }, + /* 2 */ { MAD_F(0x050a28be) /* 0.314980262 */, 3 }, + /* 3 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 4 }, + /* 4 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 4 }, + /* 5 */ { MAD_F(0x04466275) /* 0.267183742 */, 5 }, + /* 6 */ { MAD_F(0x05738c72) /* 0.340710111 */, 5 }, + /* 7 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 5 }, + /* 8 */ { MAD_F(0x04000000) /* 0.250000000 */, 6 }, + /* 9 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 6 }, + /* 10 */ { MAD_F(0x0562d694) /* 0.336630420 */, 6 }, + /* 11 */ { MAD_F(0x061dae96) /* 0.382246578 */, 6 }, + /* 12 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 6 }, + /* 13 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 6 }, + /* 14 */ { MAD_F(0x0437be65) /* 0.263609310 */, 7 }, + /* 15 */ { MAD_F(0x049fc824) /* 0.289009227 */, 7 }, + + /* 16 */ { MAD_F(0x050a28be) /* 0.314980262 */, 7 }, + /* 17 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 7 }, + /* 18 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 7 }, + /* 19 */ { MAD_F(0x06566361) /* 0.396090870 */, 7 }, + /* 20 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 7 }, + /* 21 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 7 }, + /* 22 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 7 }, + /* 23 */ { MAD_F(0x04168b05) /* 0.255503674 */, 8 }, + /* 24 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 8 }, + /* 25 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 8 }, + /* 26 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 8 }, + /* 27 */ { MAD_F(0x05100000) /* 0.316406250 */, 8 }, + /* 28 */ { MAD_F(0x05506451) /* 0.332126919 */, 8 }, + /* 29 */ { MAD_F(0x05918e15) /* 0.348035890 */, 8 }, + /* 30 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 8 }, + /* 31 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 8 }, + + /* 32 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 8 }, + /* 33 */ { MAD_F(0x069d9400) /* 0.413471222 */, 8 }, + /* 34 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 8 }, + /* 35 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 8 }, + /* 36 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 8 }, + /* 37 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 8 }, + /* 38 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 8 }, + /* 39 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 9 }, + /* 40 */ { MAD_F(0x04466275) /* 0.267183742 */, 9 }, + /* 41 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 9 }, + /* 42 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 9 }, + /* 43 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 9 }, + /* 44 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 9 }, + /* 45 */ { MAD_F(0x05007b49) /* 0.312617576 */, 9 }, + /* 46 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 9 }, + /* 47 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 9 }, + + /* 48 */ { MAD_F(0x05738c72) /* 0.340710111 */, 9 }, + /* 49 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 9 }, + /* 50 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 9 }, + /* 51 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 9 }, + /* 52 */ { MAD_F(0x0610b982) /* 0.379083164 */, 9 }, + /* 53 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 9 }, + /* 54 */ { MAD_F(0x0660db91) /* 0.398646895 */, 9 }, + /* 55 */ { MAD_F(0x06894c90) /* 0.408520284 */, 9 }, + /* 56 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 9 }, + /* 57 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 9 }, + /* 58 */ { MAD_F(0x07041636) /* 0.438497744 */, 9 }, + /* 59 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 9 }, + /* 60 */ { MAD_F(0x075722ef) /* 0.458773552 */, 9 }, + /* 61 */ { MAD_F(0x078102b8) /* 0.468996735 */, 9 }, + /* 62 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 9 }, + /* 63 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 9 }, + + /* 64 */ { MAD_F(0x04000000) /* 0.250000000 */, 10 }, + /* 65 */ { MAD_F(0x04156381) /* 0.255221850 */, 10 }, + /* 66 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 10 }, + /* 67 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 10 }, + /* 68 */ { MAD_F(0x045635cf) /* 0.271047409 */, 10 }, + /* 69 */ { MAD_F(0x046c083e) /* 0.276375048 */, 10 }, + /* 70 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 10 }, + /* 71 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 10 }, + /* 72 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 10 }, + /* 73 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 10 }, + /* 74 */ { MAD_F(0x04dab524) /* 0.303395408 */, 10 }, + /* 75 */ { MAD_F(0x04f12624) /* 0.308874267 */, 10 }, + /* 76 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 10 }, + /* 77 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 10 }, + /* 78 */ { MAD_F(0x053511cb) /* 0.325456423 */, 10 }, + /* 79 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 10 }, + + /* 80 */ { MAD_F(0x0562d694) /* 0.336630420 */, 10 }, + /* 81 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 10 }, + /* 82 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 10 }, + /* 83 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 10 }, + /* 84 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 10 }, + /* 85 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 10 }, + /* 86 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 10 }, + /* 87 */ { MAD_F(0x0606012b) /* 0.376465960 */, 10 }, + /* 88 */ { MAD_F(0x061dae96) /* 0.382246578 */, 10 }, + /* 89 */ { MAD_F(0x06357302) /* 0.388049134 */, 10 }, + /* 90 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 10 }, + /* 91 */ { MAD_F(0x0665402d) /* 0.399719406 */, 10 }, + /* 92 */ { MAD_F(0x067d4896) /* 0.405586801 */, 10 }, + /* 93 */ { MAD_F(0x06956753) /* 0.411475493 */, 10 }, + /* 94 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 10 }, + /* 95 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 10 }, + + /* 96 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 10 }, + /* 97 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 10 }, + /* 98 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 10 }, + /* 99 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 10 }, + /* 100 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 10 }, + /* 101 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 10 }, + /* 102 */ { MAD_F(0x07724f64) /* 0.465407744 */, 10 }, + /* 103 */ { MAD_F(0x078b4514) /* 0.471501425 */, 10 }, + /* 104 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 10 }, + /* 105 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 10 }, + /* 106 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 10 }, + /* 107 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 10 }, + /* 108 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 11 }, + /* 109 */ { MAD_F(0x04115aca) /* 0.254236974 */, 11 }, + /* 110 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 11 }, + /* 111 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 11 }, + + /* 112 */ { MAD_F(0x0437be65) /* 0.263609310 */, 11 }, + /* 113 */ { MAD_F(0x04449dee) /* 0.266752177 */, 11 }, + /* 114 */ { MAD_F(0x04518733) /* 0.269904329 */, 11 }, + /* 115 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 11 }, + /* 116 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 11 }, + /* 117 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 11 }, + /* 118 */ { MAD_F(0x04858c83) /* 0.282604707 */, 11 }, + /* 119 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 11 }, + /* 120 */ { MAD_F(0x049fc824) /* 0.289009227 */, 11 }, + /* 121 */ { MAD_F(0x04acf402) /* 0.292224893 */, 11 }, + /* 122 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 11 }, + /* 123 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 11 }, + /* 124 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 11 }, + /* 125 */ { MAD_F(0x04e20000) /* 0.305175781 */, 11 }, + /* 126 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 11 }, + /* 127 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 11 }, + + /* 128 */ { MAD_F(0x050a28be) /* 0.314980262 */, 11 }, + /* 129 */ { MAD_F(0x05179da4) /* 0.318265572 */, 11 }, + /* 130 */ { MAD_F(0x05251b73) /* 0.321559381 */, 11 }, + /* 131 */ { MAD_F(0x0532a220) /* 0.324861647 */, 11 }, + /* 132 */ { MAD_F(0x054031a0) /* 0.328172327 */, 11 }, + /* 133 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 11 }, + /* 134 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 11 }, + /* 135 */ { MAD_F(0x0569149c) /* 0.338154423 */, 11 }, + /* 136 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 11 }, + /* 137 */ { MAD_F(0x058481e9) /* 0.344850455 */, 11 }, + /* 138 */ { MAD_F(0x0592456d) /* 0.348210741 */, 11 }, + /* 139 */ { MAD_F(0x05a01176) /* 0.351579152 */, 11 }, + /* 140 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 11 }, + /* 141 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 11 }, + /* 142 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 11 }, + /* 143 */ { MAD_F(0x05d79601) /* 0.365133291 */, 11 }, + + /* 144 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 11 }, + /* 145 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 11 }, + /* 146 */ { MAD_F(0x060190ee) /* 0.375382356 */, 11 }, + /* 147 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 11 }, + /* 148 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 11 }, + /* 149 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 11 }, + /* 150 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 11 }, + /* 151 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 11 }, + /* 152 */ { MAD_F(0x06566361) /* 0.396090870 */, 11 }, + /* 153 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 11 }, + /* 154 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 11 }, + /* 155 */ { MAD_F(0x068138f3) /* 0.406548452 */, 11 }, + /* 156 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 11 }, + /* 157 */ { MAD_F(0x069deed1) /* 0.413557833 */, 11 }, + /* 158 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 11 }, + /* 159 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 11 }, + + /* 160 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 11 }, + /* 161 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 11 }, + /* 162 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 11 }, + /* 163 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 11 }, + /* 164 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 11 }, + /* 165 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 11 }, + /* 166 */ { MAD_F(0x0720a087) /* 0.445465593 */, 11 }, + /* 167 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 11 }, + /* 168 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 11 }, + /* 169 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 11 }, + /* 170 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 11 }, + /* 171 */ { MAD_F(0x076a454c) /* 0.463444993 */, 11 }, + /* 172 */ { MAD_F(0x07791620) /* 0.467062117 */, 11 }, + /* 173 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 11 }, + /* 174 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 11 }, + /* 175 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 11 }, + + /* 176 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 11 }, + /* 177 */ { MAD_F(0x07c39812) /* 0.485252449 */, 11 }, + /* 178 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 11 }, + /* 179 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 11 }, + /* 180 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 11 }, + /* 181 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 11 }, + /* 182 */ { MAD_F(0x0407673f) /* 0.251807447 */, 12 }, + /* 183 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 12 }, + /* 184 */ { MAD_F(0x04168b05) /* 0.255503674 */, 12 }, + /* 185 */ { MAD_F(0x041e2230) /* 0.257356825 */, 12 }, + /* 186 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 12 }, + /* 187 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 12 }, + /* 188 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 12 }, + /* 189 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 12 }, + /* 190 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 12 }, + /* 191 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 12 }, + + /* 192 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 12 }, + /* 193 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 12 }, + /* 194 */ { MAD_F(0x04630eed) /* 0.274184158 */, 12 }, + /* 195 */ { MAD_F(0x046ac896) /* 0.276070203 */, 12 }, + /* 196 */ { MAD_F(0x047285a2) /* 0.277959474 */, 12 }, + /* 197 */ { MAD_F(0x047a460c) /* 0.279851960 */, 12 }, + /* 198 */ { MAD_F(0x048209d3) /* 0.281747652 */, 12 }, + /* 199 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 12 }, + /* 200 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 12 }, + /* 201 */ { MAD_F(0x04996935) /* 0.287453849 */, 12 }, + /* 202 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 12 }, + /* 203 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 12 }, + /* 204 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 12 }, + /* 205 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 12 }, + /* 206 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 12 }, + /* 207 */ { MAD_F(0x04c88135) /* 0.298951346 */, 12 }, + + /* 208 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 12 }, + /* 209 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 12 }, + /* 210 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 12 }, + /* 211 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 12 }, + /* 212 */ { MAD_F(0x04f01963) /* 0.308617963 */, 12 }, + /* 213 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 12 }, + /* 214 */ { MAD_F(0x05000655) /* 0.312506041 */, 12 }, + /* 215 */ { MAD_F(0x05080195) /* 0.314454634 */, 12 }, + /* 216 */ { MAD_F(0x05100000) /* 0.316406250 */, 12 }, + /* 217 */ { MAD_F(0x05180194) /* 0.318360880 */, 12 }, + /* 218 */ { MAD_F(0x0520064f) /* 0.320318516 */, 12 }, + /* 219 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 12 }, + /* 220 */ { MAD_F(0x0530192e) /* 0.324242764 */, 12 }, + /* 221 */ { MAD_F(0x0538274e) /* 0.326209359 */, 12 }, + /* 222 */ { MAD_F(0x0540388a) /* 0.328178922 */, 12 }, + /* 223 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 12 }, + + /* 224 */ { MAD_F(0x05506451) /* 0.332126919 */, 12 }, + /* 225 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 12 }, + /* 226 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 12 }, + /* 227 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 12 }, + /* 228 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 12 }, + /* 229 */ { MAD_F(0x05790793) /* 0.342048241 */, 12 }, + /* 230 */ { MAD_F(0x05813162) /* 0.344041237 */, 12 }, + /* 231 */ { MAD_F(0x05895e39) /* 0.346037122 */, 12 }, + /* 232 */ { MAD_F(0x05918e15) /* 0.348035890 */, 12 }, + /* 233 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 12 }, + /* 234 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 12 }, + /* 235 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 12 }, + /* 236 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 12 }, + /* 237 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 12 }, + /* 238 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 12 }, + /* 239 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 12 }, + + /* 240 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 12 }, + /* 241 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 12 }, + /* 242 */ { MAD_F(0x05e41105) /* 0.368180294 */, 12 }, + /* 243 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 12 }, + /* 244 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 12 }, + /* 245 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 12 }, + /* 246 */ { MAD_F(0x060564b1) /* 0.376316732 */, 12 }, + /* 247 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 12 }, + /* 248 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 12 }, + /* 249 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 12 }, + /* 250 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 12 }, + /* 251 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 12 }, + /* 252 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 12 }, + /* 253 */ { MAD_F(0x06402666) /* 0.390661620 */, 12 }, + /* 254 */ { MAD_F(0x064896a7) /* 0.392721798 */, 12 }, + /* 255 */ { MAD_F(0x065109be) /* 0.394784681 */, 12 }, + + /* 256 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 12 }, + /* 257 */ { MAD_F(0x0661f867) /* 0.398918536 */, 12 }, + /* 258 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 12 }, + /* 259 */ { MAD_F(0x0672f252) /* 0.403063128 */, 12 }, + /* 260 */ { MAD_F(0x067b737c) /* 0.405139433 */, 12 }, + /* 261 */ { MAD_F(0x0683f771) /* 0.407218402 */, 12 }, + /* 262 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 12 }, + /* 263 */ { MAD_F(0x069507b5) /* 0.411384303 */, 12 }, + /* 264 */ { MAD_F(0x069d9400) /* 0.413471222 */, 12 }, + /* 265 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 12 }, + /* 266 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 12 }, + /* 267 */ { MAD_F(0x06b74971) /* 0.419747773 */, 12 }, + /* 268 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 12 }, + /* 269 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 12 }, + /* 270 */ { MAD_F(0x06d11794) /* 0.426047876 */, 12 }, + /* 271 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 12 }, + + /* 272 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 12 }, + /* 273 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 12 }, + /* 274 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 12 }, + /* 275 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 12 }, + /* 276 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 12 }, + /* 277 */ { MAD_F(0x070dacea) /* 0.440838732 */, 12 }, + /* 278 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 12 }, + /* 279 */ { MAD_F(0x071f1459) /* 0.445087765 */, 12 }, + /* 280 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 12 }, + /* 281 */ { MAD_F(0x07308671) /* 0.449346964 */, 12 }, + /* 282 */ { MAD_F(0x07394378) /* 0.451480360 */, 12 }, + /* 283 */ { MAD_F(0x07420325) /* 0.453616280 */, 12 }, + /* 284 */ { MAD_F(0x074ac575) /* 0.455754717 */, 12 }, + /* 285 */ { MAD_F(0x07538a67) /* 0.457895665 */, 12 }, + /* 286 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 12 }, + /* 287 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 12 }, + + /* 288 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 12 }, + /* 289 */ { MAD_F(0x0776b867) /* 0.466484455 */, 12 }, + /* 290 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 12 }, + /* 291 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 12 }, + /* 292 */ { MAD_F(0x07913641) /* 0.472952132 */, 12 }, + /* 293 */ { MAD_F(0x079a100c) /* 0.475112962 */, 12 }, + /* 294 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 12 }, + /* 295 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 12 }, + /* 296 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 12 }, + /* 297 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 12 }, + /* 298 */ { MAD_F(0x07c67798) /* 0.485953899 */, 12 }, + /* 299 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 12 }, + /* 300 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 12 }, + /* 301 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 12 }, + /* 302 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 12 }, + /* 303 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 12 }, + + /* 304 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 12 }, + /* 305 */ { MAD_F(0x0402868e) /* 0.250616605 */, 13 }, + /* 306 */ { MAD_F(0x040703ff) /* 0.251712795 */, 13 }, + /* 307 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 13 }, + /* 308 */ { MAD_F(0x041002a1) /* 0.253908756 */, 13 }, + /* 309 */ { MAD_F(0x041483d1) /* 0.255008523 */, 13 }, + /* 310 */ { MAD_F(0x04190640) /* 0.256109476 */, 13 }, + /* 311 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 13 }, + /* 312 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 13 }, + /* 313 */ { MAD_F(0x042694fe) /* 0.259419433 */, 13 }, + /* 314 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 13 }, + /* 315 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 13 }, + /* 316 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 13 }, + /* 317 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 13 }, + /* 318 */ { MAD_F(0x043d4635) /* 0.264959533 */, 13 }, + /* 319 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 13 }, + + /* 320 */ { MAD_F(0x04466275) /* 0.267183742 */, 13 }, + /* 321 */ { MAD_F(0x044af269) /* 0.268297587 */, 13 }, + /* 322 */ { MAD_F(0x044f8393) /* 0.269412589 */, 13 }, + /* 323 */ { MAD_F(0x045415f3) /* 0.270528746 */, 13 }, + /* 324 */ { MAD_F(0x0458a989) /* 0.271646056 */, 13 }, + /* 325 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 13 }, + /* 326 */ { MAD_F(0x0461d451) /* 0.273884123 */, 13 }, + /* 327 */ { MAD_F(0x04666b83) /* 0.275004875 */, 13 }, + /* 328 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 13 }, + /* 329 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 13 }, + /* 330 */ { MAD_F(0x04743847) /* 0.278373983 */, 13 }, + /* 331 */ { MAD_F(0x0478d440) /* 0.279499294 */, 13 }, + /* 332 */ { MAD_F(0x047d716a) /* 0.280625739 */, 13 }, + /* 333 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 13 }, + /* 334 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 13 }, + /* 335 */ { MAD_F(0x048b5003) /* 0.284011853 */, 13 }, + + /* 336 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 13 }, + /* 337 */ { MAD_F(0x049494fb) /* 0.286274891 */, 13 }, + /* 338 */ { MAD_F(0x0499393a) /* 0.287408091 */, 13 }, + /* 339 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 13 }, + /* 340 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 13 }, + /* 341 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 13 }, + /* 342 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 13 }, + /* 343 */ { MAD_F(0x04b08000) /* 0.293090820 */, 13 }, + /* 344 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 13 }, + /* 345 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 13 }, + /* 346 */ { MAD_F(0x04be8537) /* 0.296513762 */, 13 }, + /* 347 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 13 }, + /* 348 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 13 }, + /* 349 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 13 }, + /* 350 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 13 }, + /* 351 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 13 }, + + /* 352 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 13 }, + /* 353 */ { MAD_F(0x04df6458) /* 0.304539056 */, 13 }, + /* 354 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 13 }, + /* 355 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 13 }, + /* 356 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 13 }, + /* 357 */ { MAD_F(0x04f24618) /* 0.309148880 */, 13 }, + /* 358 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 13 }, + /* 359 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 13 }, + /* 360 */ { MAD_F(0x05007b49) /* 0.312617576 */, 13 }, + /* 361 */ { MAD_F(0x050539ef) /* 0.313775954 */, 13 }, + /* 362 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 13 }, + /* 363 */ { MAD_F(0x050eba98) /* 0.316095920 */, 13 }, + /* 364 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 13 }, + /* 365 */ { MAD_F(0x05183fba) /* 0.318420150 */, 13 }, + /* 366 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 13 }, + /* 367 */ { MAD_F(0x0521c950) /* 0.320748629 */, 13 }, + + /* 368 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 13 }, + /* 369 */ { MAD_F(0x052b5757) /* 0.323081342 */, 13 }, + /* 370 */ { MAD_F(0x05302003) /* 0.324249281 */, 13 }, + /* 371 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 13 }, + /* 372 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 13 }, + /* 373 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 13 }, + /* 374 */ { MAD_F(0x05434db9) /* 0.328931546 */, 13 }, + /* 375 */ { MAD_F(0x05481be5) /* 0.330104730 */, 13 }, + /* 376 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 13 }, + /* 377 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 13 }, + /* 378 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 13 }, + /* 379 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 13 }, + /* 380 */ { MAD_F(0x05603321) /* 0.335986261 */, 13 }, + /* 381 */ { MAD_F(0x056507d6) /* 0.337165677 */, 13 }, + /* 382 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 13 }, + /* 383 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 13 }, + + /* 384 */ { MAD_F(0x05738c72) /* 0.340710111 */, 13 }, + /* 385 */ { MAD_F(0x05786578) /* 0.341893646 */, 13 }, + /* 386 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 13 }, + /* 387 */ { MAD_F(0x05821abf) /* 0.344263788 */, 13 }, + /* 388 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 13 }, + /* 389 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 13 }, + /* 390 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 13 }, + /* 391 */ { MAD_F(0x05959222) /* 0.349016318 */, 13 }, + /* 392 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 13 }, + /* 393 */ { MAD_F(0x059f5438) /* 0.351398678 */, 13 }, + /* 394 */ { MAD_F(0x05a436da) /* 0.352591376 */, 13 }, + /* 395 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 13 }, + /* 396 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 13 }, + /* 397 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 13 }, + /* 398 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 13 }, + /* 399 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 13 }, + + /* 400 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 13 }, + /* 401 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 13 }, + /* 402 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 13 }, + /* 403 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 13 }, + /* 404 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 13 }, + /* 405 */ { MAD_F(0x05da394d) /* 0.365777304 */, 13 }, + /* 406 */ { MAD_F(0x05df2885) /* 0.366982004 */, 13 }, + /* 407 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 13 }, + /* 408 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 13 }, + /* 409 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 13 }, + /* 410 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 13 }, + /* 411 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 13 }, + /* 412 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 13 }, + /* 413 */ { MAD_F(0x0601d004) /* 0.375442522 */, 13 }, + /* 414 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 13 }, + /* 415 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 13 }, + + /* 416 */ { MAD_F(0x0610b982) /* 0.379083164 */, 13 }, + /* 417 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 13 }, + /* 418 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 13 }, + /* 419 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 13 }, + /* 420 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 13 }, + /* 421 */ { MAD_F(0x0629a863) /* 0.385170352 */, 13 }, + /* 422 */ { MAD_F(0x062ea802) /* 0.386390694 */, 13 }, + /* 423 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 13 }, + /* 424 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 13 }, + /* 425 */ { MAD_F(0x063dacee) /* 0.390057497 */, 13 }, + /* 426 */ { MAD_F(0x0642b096) /* 0.391281687 */, 13 }, + /* 427 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 13 }, + /* 428 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 13 }, + /* 429 */ { MAD_F(0x0651c193) /* 0.394959999 */, 13 }, + /* 430 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 13 }, + /* 431 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 13 }, + + /* 432 */ { MAD_F(0x0660db91) /* 0.398646895 */, 13 }, + /* 433 */ { MAD_F(0x0665e639) /* 0.399877761 */, 13 }, + /* 434 */ { MAD_F(0x066af1df) /* 0.401109575 */, 13 }, + /* 435 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 13 }, + /* 436 */ { MAD_F(0x06750c26) /* 0.403576041 */, 13 }, + /* 437 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 13 }, + /* 438 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 13 }, + /* 439 */ { MAD_F(0x06843afb) /* 0.407282813 */, 13 }, + /* 440 */ { MAD_F(0x06894c90) /* 0.408520284 */, 13 }, + /* 441 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 13 }, + /* 442 */ { MAD_F(0x069372ae) /* 0.410998038 */, 13 }, + /* 443 */ { MAD_F(0x06988735) /* 0.412238319 */, 13 }, + /* 444 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 13 }, + /* 445 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 13 }, + /* 446 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 13 }, + /* 447 */ { MAD_F(0x06ace318) /* 0.417208762 */, 13 }, + + /* 448 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 13 }, + /* 449 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 13 }, + /* 450 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 13 }, + /* 451 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 13 }, + /* 452 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 13 }, + /* 453 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 13 }, + /* 454 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 13 }, + /* 455 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 13 }, + /* 456 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 13 }, + /* 457 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 13 }, + /* 458 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 13 }, + /* 459 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 13 }, + /* 460 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 13 }, + /* 461 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 13 }, + /* 462 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 13 }, + /* 463 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 13 }, + + /* 464 */ { MAD_F(0x07041636) /* 0.438497744 */, 13 }, + /* 465 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 13 }, + /* 466 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 13 }, + /* 467 */ { MAD_F(0x07139641) /* 0.442281965 */, 13 }, + /* 468 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 13 }, + /* 469 */ { MAD_F(0x071df058) /* 0.444809288 */, 13 }, + /* 470 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 13 }, + /* 471 */ { MAD_F(0x07284e34) /* 0.447340205 */, 13 }, + /* 472 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 13 }, + /* 473 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 13 }, + /* 474 */ { MAD_F(0x0737e209) /* 0.451143300 */, 13 }, + /* 475 */ { MAD_F(0x073d1530) /* 0.452412785 */, 13 }, + /* 476 */ { MAD_F(0x07424946) /* 0.453683161 */, 13 }, + /* 477 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 13 }, + /* 478 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 13 }, + /* 479 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 13 }, + + /* 480 */ { MAD_F(0x075722ef) /* 0.458773552 */, 13 }, + /* 481 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 13 }, + /* 482 */ { MAD_F(0x07619557) /* 0.461324062 */, 13 }, + /* 483 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 13 }, + /* 484 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 13 }, + /* 485 */ { MAD_F(0x077147e2) /* 0.465156443 */, 13 }, + /* 486 */ { MAD_F(0x0776853e) /* 0.466435663 */, 13 }, + /* 487 */ { MAD_F(0x077bc385) /* 0.467715761 */, 13 }, + /* 488 */ { MAD_F(0x078102b8) /* 0.468996735 */, 13 }, + /* 489 */ { MAD_F(0x078642d6) /* 0.470278584 */, 13 }, + /* 490 */ { MAD_F(0x078b83de) /* 0.471561307 */, 13 }, + /* 491 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 13 }, + /* 492 */ { MAD_F(0x079608ae) /* 0.474129372 */, 13 }, + /* 493 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 13 }, + /* 494 */ { MAD_F(0x07a09124) /* 0.476700918 */, 13 }, + /* 495 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 13 }, + + /* 496 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 13 }, + /* 497 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 13 }, + /* 498 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 13 }, + /* 499 */ { MAD_F(0x07baf635) /* 0.483144957 */, 13 }, + /* 500 */ { MAD_F(0x07c04056) /* 0.484436356 */, 13 }, + /* 501 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 13 }, + /* 502 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 13 }, + /* 503 */ { MAD_F(0x07d02424) /* 0.488315717 */, 13 }, + /* 504 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 13 }, + /* 505 */ { MAD_F(0x07dac083) /* 0.490906249 */, 13 }, + /* 506 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 13 }, + /* 507 */ { MAD_F(0x07e56078) /* 0.493500203 */, 13 }, + /* 508 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 13 }, + /* 509 */ { MAD_F(0x07f00401) /* 0.496097570 */, 13 }, + /* 510 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 13 }, + /* 511 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 13 }, + + /* 512 */ { MAD_F(0x04000000) /* 0.250000000 */, 14 }, + /* 513 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 14 }, + /* 514 */ { MAD_F(0x04055638) /* 0.251302930 */, 14 }, + /* 515 */ { MAD_F(0x040801ff) /* 0.251955030 */, 14 }, + /* 516 */ { MAD_F(0x040aae37) /* 0.252607552 */, 14 }, + /* 517 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 14 }, + /* 518 */ { MAD_F(0x041007fa) /* 0.253913860 */, 14 }, + /* 519 */ { MAD_F(0x0412b586) /* 0.254567645 */, 14 }, + /* 520 */ { MAD_F(0x04156381) /* 0.255221850 */, 14 }, + /* 521 */ { MAD_F(0x041811ee) /* 0.255876475 */, 14 }, + /* 522 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 14 }, + /* 523 */ { MAD_F(0x041d7018) /* 0.257186980 */, 14 }, + /* 524 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 14 }, + /* 525 */ { MAD_F(0x0422d003) /* 0.258499157 */, 14 }, + /* 526 */ { MAD_F(0x042580a0) /* 0.259155872 */, 14 }, + /* 527 */ { MAD_F(0x042831ad) /* 0.259813002 */, 14 }, + + /* 528 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 14 }, + /* 529 */ { MAD_F(0x042d9516) /* 0.261128510 */, 14 }, + /* 530 */ { MAD_F(0x04304772) /* 0.261786886 */, 14 }, + /* 531 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 14 }, + /* 532 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 14 }, + /* 533 */ { MAD_F(0x0438611f) /* 0.263764497 */, 14 }, + /* 534 */ { MAD_F(0x043b1536) /* 0.264424527 */, 14 }, + /* 535 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 14 }, + /* 536 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 14 }, + /* 537 */ { MAD_F(0x04433414) /* 0.266407088 */, 14 }, + /* 538 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 14 }, + /* 539 */ { MAD_F(0x0448a024) /* 0.267730848 */, 14 }, + /* 540 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 14 }, + /* 541 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 14 }, + /* 542 */ { MAD_F(0x0450c575) /* 0.269719560 */, 14 }, + /* 543 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 14 }, + + /* 544 */ { MAD_F(0x045635cf) /* 0.271047409 */, 14 }, + /* 545 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 14 }, + /* 546 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 14 }, + /* 547 */ { MAD_F(0x045e6188) /* 0.273042234 */, 14 }, + /* 548 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 14 }, + /* 549 */ { MAD_F(0x0463d625) /* 0.274374147 */, 14 }, + /* 550 */ { MAD_F(0x04669116) /* 0.275040710 */, 14 }, + /* 551 */ { MAD_F(0x04694c74) /* 0.275707677 */, 14 }, + /* 552 */ { MAD_F(0x046c083e) /* 0.276375048 */, 14 }, + /* 553 */ { MAD_F(0x046ec474) /* 0.277042822 */, 14 }, + /* 554 */ { MAD_F(0x04718116) /* 0.277710999 */, 14 }, + /* 555 */ { MAD_F(0x04743e25) /* 0.278379578 */, 14 }, + /* 556 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 14 }, + /* 557 */ { MAD_F(0x0479b984) /* 0.279717940 */, 14 }, + /* 558 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 14 }, + /* 559 */ { MAD_F(0x047f3693) /* 0.281057905 */, 14 }, + + /* 560 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 14 }, + /* 561 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 14 }, + /* 562 */ { MAD_F(0x0487754c) /* 0.283070849 */, 14 }, + /* 563 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 14 }, + /* 564 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 14 }, + /* 565 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 14 }, + /* 566 */ { MAD_F(0x04927972) /* 0.285760350 */, 14 }, + /* 567 */ { MAD_F(0x04953b85) /* 0.286433717 */, 14 }, + /* 568 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 14 }, + /* 569 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 14 }, + /* 570 */ { MAD_F(0x049d843e) /* 0.288456194 */, 14 }, + /* 571 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 14 }, + /* 572 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 14 }, + /* 573 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 14 }, + /* 574 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 14 }, + /* 575 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 14 }, + + /* 576 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 14 }, + /* 577 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 14 }, + /* 578 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 14 }, + /* 579 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 14 }, + /* 580 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 14 }, + /* 581 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 14 }, + /* 582 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 14 }, + /* 583 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 14 }, + /* 584 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 14 }, + /* 585 */ { MAD_F(0x04c72771) /* 0.298621598 */, 14 }, + /* 586 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 14 }, + /* 587 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 14 }, + /* 588 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 14 }, + /* 589 */ { MAD_F(0x04d25169) /* 0.301347172 */, 14 }, + /* 590 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 14 }, + /* 591 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 14 }, + + /* 592 */ { MAD_F(0x04dab524) /* 0.303395408 */, 14 }, + /* 593 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 14 }, + /* 594 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 14 }, + /* 595 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 14 }, + /* 596 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 14 }, + /* 597 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 14 }, + /* 598 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 14 }, + /* 599 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 14 }, + /* 600 */ { MAD_F(0x04f12624) /* 0.308874267 */, 14 }, + /* 601 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 14 }, + /* 602 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 14 }, + /* 603 */ { MAD_F(0x04f99721) /* 0.310935143 */, 14 }, + /* 604 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 14 }, + /* 605 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 14 }, + /* 606 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 14 }, + /* 607 */ { MAD_F(0x0504de05) /* 0.313688296 */, 14 }, + + /* 608 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 14 }, + /* 609 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 14 }, + /* 610 */ { MAD_F(0x050d575b) /* 0.315757136 */, 14 }, + /* 611 */ { MAD_F(0x05102b42) /* 0.316447504 */, 14 }, + /* 612 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 14 }, + /* 613 */ { MAD_F(0x0515d440) /* 0.317829370 */, 14 }, + /* 614 */ { MAD_F(0x0518a956) /* 0.318520867 */, 14 }, + /* 615 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 14 }, + /* 616 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 14 }, + /* 617 */ { MAD_F(0x05212af5) /* 0.320597609 */, 14 }, + /* 618 */ { MAD_F(0x0524019e) /* 0.321290606 */, 14 }, + /* 619 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 14 }, + /* 620 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 14 }, + /* 621 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 14 }, + /* 622 */ { MAD_F(0x052f602c) /* 0.324066327 */, 14 }, + /* 623 */ { MAD_F(0x053238ca) /* 0.324761189 */, 14 }, + + /* 624 */ { MAD_F(0x053511cb) /* 0.325456423 */, 14 }, + /* 625 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 14 }, + /* 626 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 14 }, + /* 627 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 14 }, + /* 628 */ { MAD_F(0x054079b5) /* 0.328241070 */, 14 }, + /* 629 */ { MAD_F(0x054354a8) /* 0.328938157 */, 14 }, + /* 630 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 14 }, + /* 631 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 14 }, + /* 632 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 14 }, + /* 633 */ { MAD_F(0x054ec453) /* 0.331730198 */, 14 }, + /* 634 */ { MAD_F(0x0551a134) /* 0.332429129 */, 14 }, + /* 635 */ { MAD_F(0x05547e79) /* 0.333128427 */, 14 }, + /* 636 */ { MAD_F(0x05575c20) /* 0.333828093 */, 14 }, + /* 637 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 14 }, + /* 638 */ { MAD_F(0x055d1896) /* 0.335228525 */, 14 }, + /* 639 */ { MAD_F(0x055ff764) /* 0.335929290 */, 14 }, + + /* 640 */ { MAD_F(0x0562d694) /* 0.336630420 */, 14 }, + /* 641 */ { MAD_F(0x0565b627) /* 0.337331916 */, 14 }, + /* 642 */ { MAD_F(0x0568961b) /* 0.338033777 */, 14 }, + /* 643 */ { MAD_F(0x056b7671) /* 0.338736002 */, 14 }, + /* 644 */ { MAD_F(0x056e5729) /* 0.339438592 */, 14 }, + /* 645 */ { MAD_F(0x05713843) /* 0.340141545 */, 14 }, + /* 646 */ { MAD_F(0x057419be) /* 0.340844862 */, 14 }, + /* 647 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 14 }, + /* 648 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 14 }, + /* 649 */ { MAD_F(0x057cc077) /* 0.342956988 */, 14 }, + /* 650 */ { MAD_F(0x057fa378) /* 0.343661754 */, 14 }, + /* 651 */ { MAD_F(0x058286d9) /* 0.344366882 */, 14 }, + /* 652 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 14 }, + /* 653 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 14 }, + /* 654 */ { MAD_F(0x058b3342) /* 0.346484431 */, 14 }, + /* 655 */ { MAD_F(0x058e1827) /* 0.347191002 */, 14 }, + + /* 656 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 14 }, + /* 657 */ { MAD_F(0x0593e311) /* 0.348605221 */, 14 }, + /* 658 */ { MAD_F(0x0596c917) /* 0.349312869 */, 14 }, + /* 659 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 14 }, + /* 660 */ { MAD_F(0x059c9643) /* 0.350729240 */, 14 }, + /* 661 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 14 }, + /* 662 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 14 }, + /* 663 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 14 }, + /* 664 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 14 }, + /* 665 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 14 }, + /* 666 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 14 }, + /* 667 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 14 }, + /* 668 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 14 }, + /* 669 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 14 }, + /* 670 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 14 }, + /* 671 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 14 }, + + /* 672 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 14 }, + /* 673 */ { MAD_F(0x05c27057) /* 0.359970419 */, 14 }, + /* 674 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 14 }, + /* 675 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 14 }, + /* 676 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 14 }, + /* 677 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 14 }, + /* 678 */ { MAD_F(0x05d11001) /* 0.363540655 */, 14 }, + /* 679 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 14 }, + /* 680 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 14 }, + /* 681 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 14 }, + /* 682 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 14 }, + /* 683 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 14 }, + /* 684 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 14 }, + /* 685 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 14 }, + /* 686 */ { MAD_F(0x05e88904) /* 0.369271294 */, 14 }, + /* 687 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 14 }, + + /* 688 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 14 }, + /* 689 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 14 }, + /* 690 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 14 }, + /* 691 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 14 }, + /* 692 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 14 }, + /* 693 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 14 }, + /* 694 */ { MAD_F(0x0600196e) /* 0.375024253 */, 14 }, + /* 695 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 14 }, + /* 696 */ { MAD_F(0x0606012b) /* 0.376465960 */, 14 }, + /* 697 */ { MAD_F(0x0608f595) /* 0.377187332 */, 14 }, + /* 698 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 14 }, + /* 699 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 14 }, + /* 700 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 14 }, + /* 701 */ { MAD_F(0x0614cada) /* 0.380076266 */, 14 }, + /* 702 */ { MAD_F(0x0617c112) /* 0.380799360 */, 14 }, + /* 703 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 14 }, + + /* 704 */ { MAD_F(0x061dae96) /* 0.382246578 */, 14 }, + /* 705 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 14 }, + /* 706 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 14 }, + /* 707 */ { MAD_F(0x0626958f) /* 0.384419975 */, 14 }, + /* 708 */ { MAD_F(0x06298def) /* 0.385145124 */, 14 }, + /* 709 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 14 }, + /* 710 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 14 }, + /* 711 */ { MAD_F(0x06327934) /* 0.387322621 */, 14 }, + /* 712 */ { MAD_F(0x06357302) /* 0.388049134 */, 14 }, + /* 713 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 14 }, + /* 714 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 14 }, + /* 715 */ { MAD_F(0x063e6290) /* 0.390230715 */, 14 }, + /* 716 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 14 }, + /* 717 */ { MAD_F(0x06445960) /* 0.391686799 */, 14 }, + /* 718 */ { MAD_F(0x06475551) /* 0.392415349 */, 14 }, + /* 719 */ { MAD_F(0x064a519c) /* 0.393144238 */, 14 }, + + /* 720 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 14 }, + /* 721 */ { MAD_F(0x06504b44) /* 0.394603028 */, 14 }, + /* 722 */ { MAD_F(0x0653489f) /* 0.395332930 */, 14 }, + /* 723 */ { MAD_F(0x06564655) /* 0.396063168 */, 14 }, + /* 724 */ { MAD_F(0x06594465) /* 0.396793743 */, 14 }, + /* 725 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 14 }, + /* 726 */ { MAD_F(0x065f4195) /* 0.398255903 */, 14 }, + /* 727 */ { MAD_F(0x066240b4) /* 0.398987487 */, 14 }, + /* 728 */ { MAD_F(0x0665402d) /* 0.399719406 */, 14 }, + /* 729 */ { MAD_F(0x06684000) /* 0.400451660 */, 14 }, + /* 730 */ { MAD_F(0x066b402d) /* 0.401184249 */, 14 }, + /* 731 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 14 }, + /* 732 */ { MAD_F(0x06714194) /* 0.402650431 */, 14 }, + /* 733 */ { MAD_F(0x067442ce) /* 0.403384024 */, 14 }, + /* 734 */ { MAD_F(0x06774462) /* 0.404117949 */, 14 }, + /* 735 */ { MAD_F(0x067a464f) /* 0.404852209 */, 14 }, + + /* 736 */ { MAD_F(0x067d4896) /* 0.405586801 */, 14 }, + /* 737 */ { MAD_F(0x06804b36) /* 0.406321726 */, 14 }, + /* 738 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 14 }, + /* 739 */ { MAD_F(0x06865181) /* 0.407792573 */, 14 }, + /* 740 */ { MAD_F(0x0689552c) /* 0.408528495 */, 14 }, + /* 741 */ { MAD_F(0x068c5931) /* 0.409264748 */, 14 }, + /* 742 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 14 }, + /* 743 */ { MAD_F(0x06926245) /* 0.410738247 */, 14 }, + /* 744 */ { MAD_F(0x06956753) /* 0.411475493 */, 14 }, + /* 745 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 14 }, + /* 746 */ { MAD_F(0x069b727b) /* 0.412950976 */, 14 }, + /* 747 */ { MAD_F(0x069e7894) /* 0.413689213 */, 14 }, + /* 748 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 14 }, + /* 749 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 14 }, + /* 750 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 14 }, + /* 751 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 14 }, + + /* 752 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 14 }, + /* 753 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 14 }, + /* 754 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 14 }, + /* 755 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 14 }, + /* 756 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 14 }, + /* 757 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 14 }, + /* 758 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 14 }, + /* 759 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 14 }, + /* 760 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 14 }, + /* 761 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 14 }, + /* 762 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 14 }, + /* 763 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 14 }, + /* 764 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 14 }, + /* 765 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 14 }, + /* 766 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 14 }, + /* 767 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 14 }, + + /* 768 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 14 }, + /* 769 */ { MAD_F(0x06e15595) /* 0.430013259 */, 14 }, + /* 770 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 14 }, + /* 771 */ { MAD_F(0x06e771db) /* 0.431505065 */, 14 }, + /* 772 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 14 }, + /* 773 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 14 }, + /* 774 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 14 }, + /* 775 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 14 }, + /* 776 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 14 }, + /* 777 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 14 }, + /* 778 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 14 }, + /* 779 */ { MAD_F(0x06fff073) /* 0.437485172 */, 14 }, + /* 780 */ { MAD_F(0x070301ca) /* 0.438234130 */, 14 }, + /* 781 */ { MAD_F(0x07061377) /* 0.438983408 */, 14 }, + /* 782 */ { MAD_F(0x0709257a) /* 0.439733006 */, 14 }, + /* 783 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 14 }, + + /* 784 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 14 }, + /* 785 */ { MAD_F(0x07125d84) /* 0.441983717 */, 14 }, + /* 786 */ { MAD_F(0x071570de) /* 0.442734592 */, 14 }, + /* 787 */ { MAD_F(0x0718848d) /* 0.443485785 */, 14 }, + /* 788 */ { MAD_F(0x071b9891) /* 0.444237296 */, 14 }, + /* 789 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 14 }, + /* 790 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 14 }, + /* 791 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 14 }, + /* 792 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 14 }, + /* 793 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 14 }, + /* 794 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 14 }, + /* 795 */ { MAD_F(0x07312e01) /* 0.449506765 */, 14 }, + /* 796 */ { MAD_F(0x073444ae) /* 0.450260813 */, 14 }, + /* 797 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 14 }, + /* 798 */ { MAD_F(0x073a7307) /* 0.451769856 */, 14 }, + /* 799 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 14 }, + + /* 800 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 14 }, + /* 801 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 14 }, + /* 802 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 14 }, + /* 803 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 14 }, + /* 804 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 14 }, + /* 805 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 14 }, + /* 806 */ { MAD_F(0x0753399d) /* 0.457818618 */, 14 }, + /* 807 */ { MAD_F(0x075653eb) /* 0.458576125 */, 14 }, + /* 808 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 14 }, + /* 809 */ { MAD_F(0x075c8983) /* 0.460092079 */, 14 }, + /* 810 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 14 }, + /* 811 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 14 }, + /* 812 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 14 }, + /* 813 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 14 }, + /* 814 */ { MAD_F(0x076c1538) /* 0.463887426 */, 14 }, + /* 815 */ { MAD_F(0x076f3224) /* 0.464647430 */, 14 }, + + /* 816 */ { MAD_F(0x07724f64) /* 0.465407744 */, 14 }, + /* 817 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 14 }, + /* 818 */ { MAD_F(0x07788add) /* 0.466929306 */, 14 }, + /* 819 */ { MAD_F(0x077ba916) /* 0.467690552 */, 14 }, + /* 820 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 14 }, + /* 821 */ { MAD_F(0x0781e683) /* 0.469213973 */, 14 }, + /* 822 */ { MAD_F(0x078505b5) /* 0.469976148 */, 14 }, + /* 823 */ { MAD_F(0x0788253b) /* 0.470738632 */, 14 }, + /* 824 */ { MAD_F(0x078b4514) /* 0.471501425 */, 14 }, + /* 825 */ { MAD_F(0x078e653f) /* 0.472264527 */, 14 }, + /* 826 */ { MAD_F(0x079185be) /* 0.473027937 */, 14 }, + /* 827 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 14 }, + /* 828 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 14 }, + /* 829 */ { MAD_F(0x079ae929) /* 0.475320014 */, 14 }, + /* 830 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 14 }, + /* 831 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 14 }, + + /* 832 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 14 }, + /* 833 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 14 }, + /* 834 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 14 }, + /* 835 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 14 }, + /* 836 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 14 }, + /* 837 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 14 }, + /* 838 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 14 }, + /* 839 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 14 }, + /* 840 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 14 }, + /* 841 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 14 }, + /* 842 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 14 }, + /* 843 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 14 }, + /* 844 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 14 }, + /* 845 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 14 }, + /* 846 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 14 }, + /* 847 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 14 }, + + /* 848 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 14 }, + /* 849 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 14 }, + /* 850 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 14 }, + /* 851 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 14 }, + /* 852 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 14 }, + /* 853 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 14 }, + /* 854 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 14 }, + /* 855 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 14 }, + /* 856 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 14 }, + /* 857 */ { MAD_F(0x07f31405) /* 0.496845266 */, 14 }, + /* 858 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 14 }, + /* 859 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 14 }, + /* 860 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 14 }, + /* 861 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 14 }, + /* 862 */ { MAD_F(0x04017659) /* 0.250357008 */, 15 }, + /* 863 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 15 }, + + /* 864 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 15 }, + /* 865 */ { MAD_F(0x0406393d) /* 0.251519431 */, 15 }, + /* 866 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 15 }, + /* 867 */ { MAD_F(0x0409669d) /* 0.252295127 */, 15 }, + /* 868 */ { MAD_F(0x040afd89) /* 0.252683198 */, 15 }, + /* 869 */ { MAD_F(0x040c949e) /* 0.253071419 */, 15 }, + /* 870 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 15 }, + /* 871 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 15 }, + /* 872 */ { MAD_F(0x04115aca) /* 0.254236974 */, 15 }, + /* 873 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 15 }, + /* 874 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 15 }, + /* 875 */ { MAD_F(0x0416225d) /* 0.255403867 */, 15 }, + /* 876 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 15 }, + /* 877 */ { MAD_F(0x041952dc) /* 0.256182537 */, 15 }, + /* 878 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 15 }, + /* 879 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 15 }, + + /* 880 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 15 }, + /* 881 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 15 }, + /* 882 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 15 }, + /* 883 */ { MAD_F(0x0422e811) /* 0.258522097 */, 15 }, + /* 884 */ { MAD_F(0x04248179) /* 0.258912540 */, 15 }, + /* 885 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 15 }, + /* 886 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 15 }, + /* 887 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 15 }, + /* 888 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 15 }, + /* 889 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 15 }, + /* 890 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 15 }, + /* 891 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 15 }, + /* 892 */ { MAD_F(0x0431524c) /* 0.262041376 */, 15 }, + /* 893 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 15 }, + /* 894 */ { MAD_F(0x0434880a) /* 0.262825051 */, 15 }, + /* 895 */ { MAD_F(0x04362324) /* 0.263217107 */, 15 }, + + /* 896 */ { MAD_F(0x0437be65) /* 0.263609310 */, 15 }, + /* 897 */ { MAD_F(0x043959cd) /* 0.264001659 */, 15 }, + /* 898 */ { MAD_F(0x043af55d) /* 0.264394153 */, 15 }, + /* 899 */ { MAD_F(0x043c9113) /* 0.264786794 */, 15 }, + /* 900 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 15 }, + /* 901 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 15 }, + /* 902 */ { MAD_F(0x04416522) /* 0.265965588 */, 15 }, + /* 903 */ { MAD_F(0x04430174) /* 0.266358810 */, 15 }, + /* 904 */ { MAD_F(0x04449dee) /* 0.266752177 */, 15 }, + /* 905 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 15 }, + /* 906 */ { MAD_F(0x0447d756) /* 0.267539347 */, 15 }, + /* 907 */ { MAD_F(0x04497445) /* 0.267933149 */, 15 }, + /* 908 */ { MAD_F(0x044b115a) /* 0.268327096 */, 15 }, + /* 909 */ { MAD_F(0x044cae96) /* 0.268721187 */, 15 }, + /* 910 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 15 }, + /* 911 */ { MAD_F(0x044fe983) /* 0.269509804 */, 15 }, + + /* 912 */ { MAD_F(0x04518733) /* 0.269904329 */, 15 }, + /* 913 */ { MAD_F(0x0453250a) /* 0.270298998 */, 15 }, + /* 914 */ { MAD_F(0x0454c308) /* 0.270693811 */, 15 }, + /* 915 */ { MAD_F(0x0456612d) /* 0.271088768 */, 15 }, + /* 916 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 15 }, + /* 917 */ { MAD_F(0x04599dea) /* 0.271879114 */, 15 }, + /* 918 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 15 }, + /* 919 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 15 }, + /* 920 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 15 }, + /* 921 */ { MAD_F(0x04601932) /* 0.273461530 */, 15 }, + /* 922 */ { MAD_F(0x0461b864) /* 0.273857492 */, 15 }, + /* 923 */ { MAD_F(0x046357bd) /* 0.274253597 */, 15 }, + /* 924 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 15 }, + /* 925 */ { MAD_F(0x046696e2) /* 0.275046238 */, 15 }, + /* 926 */ { MAD_F(0x046836ae) /* 0.275442772 */, 15 }, + /* 927 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 15 }, + + /* 928 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 15 }, + /* 929 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 15 }, + /* 930 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 15 }, + /* 931 */ { MAD_F(0x047057e8) /* 0.277427584 */, 15 }, + /* 932 */ { MAD_F(0x0471f899) /* 0.277824973 */, 15 }, + /* 933 */ { MAD_F(0x04739971) /* 0.278222505 */, 15 }, + /* 934 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 15 }, + /* 935 */ { MAD_F(0x0476db92) /* 0.279017995 */, 15 }, + /* 936 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 15 }, + /* 937 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 15 }, + /* 938 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 15 }, + /* 939 */ { MAD_F(0x047d619e) /* 0.280610675 */, 15 }, + /* 940 */ { MAD_F(0x047f0380) /* 0.281009199 */, 15 }, + /* 941 */ { MAD_F(0x0480a588) /* 0.281407864 */, 15 }, + /* 942 */ { MAD_F(0x048247b6) /* 0.281806670 */, 15 }, + /* 943 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 15 }, + + /* 944 */ { MAD_F(0x04858c83) /* 0.282604707 */, 15 }, + /* 945 */ { MAD_F(0x04872f22) /* 0.283003936 */, 15 }, + /* 946 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 15 }, + /* 947 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 15 }, + /* 948 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 15 }, + /* 949 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 15 }, + /* 950 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 15 }, + /* 951 */ { MAD_F(0x049101f8) /* 0.285402269 */, 15 }, + /* 952 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 15 }, + /* 953 */ { MAD_F(0x0494496c) /* 0.286202836 */, 15 }, + /* 954 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 15 }, + /* 955 */ { MAD_F(0x04979177) /* 0.287003963 */, 15 }, + /* 956 */ { MAD_F(0x049935b5) /* 0.287404737 */, 15 }, + /* 957 */ { MAD_F(0x049ada19) /* 0.287805650 */, 15 }, + /* 958 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 15 }, + /* 959 */ { MAD_F(0x049e2350) /* 0.288607895 */, 15 }, + + /* 960 */ { MAD_F(0x049fc824) /* 0.289009227 */, 15 }, + /* 961 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 15 }, + /* 962 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 15 }, + /* 963 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 15 }, + /* 964 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 15 }, + /* 965 */ { MAD_F(0x04a80277) /* 0.291017976 */, 15 }, + /* 966 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 15 }, + /* 967 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 15 }, + /* 968 */ { MAD_F(0x04acf402) /* 0.292224893 */, 15 }, + /* 969 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 15 }, + /* 970 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 15 }, + /* 971 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 15 }, + /* 972 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 15 }, + /* 973 */ { MAD_F(0x04b53427) /* 0.294239192 */, 15 }, + /* 974 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 15 }, + /* 975 */ { MAD_F(0x04b88207) /* 0.295045879 */, 15 }, + + /* 976 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 15 }, + /* 977 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 15 }, + /* 978 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 15 }, + /* 979 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 15 }, + /* 980 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 15 }, + /* 981 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 15 }, + /* 982 */ { MAD_F(0x04c41722) /* 0.297873624 */, 15 }, + /* 983 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 15 }, + /* 984 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 15 }, + /* 985 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 15 }, + /* 986 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 15 }, + /* 987 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 15 }, + /* 988 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 15 }, + /* 989 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 15 }, + /* 990 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 15 }, + /* 991 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 15 }, + + /* 992 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 15 }, + /* 993 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 15 }, + /* 994 */ { MAD_F(0x04d80290) /* 0.302736820 */, 15 }, + /* 995 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 15 }, + /* 996 */ { MAD_F(0x04db5679) /* 0.303549263 */, 15 }, + /* 997 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 15 }, + /* 998 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 15 }, + /* 999 */ { MAD_F(0x04e05567) /* 0.304768948 */, 15 }, + /* 1000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 15 }, + /* 1001 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 15 }, + /* 1002 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 15 }, + /* 1003 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 15 }, + /* 1004 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 15 }, + /* 1005 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 15 }, + /* 1006 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 15 }, + /* 1007 */ { MAD_F(0x04edae25) /* 0.308027406 */, 15 }, + + /* 1008 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 15 }, + /* 1009 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 15 }, + /* 1010 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 15 }, + /* 1011 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 15 }, + /* 1012 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 15 }, + /* 1013 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 15 }, + /* 1014 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 15 }, + /* 1015 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 15 }, + /* 1016 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 15 }, + /* 1017 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 15 }, + /* 1018 */ { MAD_F(0x050016f3) /* 0.312521885 */, 15 }, + /* 1019 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 15 }, + /* 1020 */ { MAD_F(0x050371a7) /* 0.313340809 */, 15 }, + /* 1021 */ { MAD_F(0x05051f37) /* 0.313750472 */, 15 }, + /* 1022 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 15 }, + /* 1023 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 15 }, + + /* 1024 */ { MAD_F(0x050a28be) /* 0.314980262 */, 15 }, + /* 1025 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 15 }, + /* 1026 */ { MAD_F(0x050d8521) /* 0.315800790 */, 15 }, + /* 1027 */ { MAD_F(0x050f3388) /* 0.316211255 */, 15 }, + /* 1028 */ { MAD_F(0x0510e213) /* 0.316621852 */, 15 }, + /* 1029 */ { MAD_F(0x051290c2) /* 0.317032582 */, 15 }, + /* 1030 */ { MAD_F(0x05143f94) /* 0.317443446 */, 15 }, + /* 1031 */ { MAD_F(0x0515ee8a) /* 0.317854442 */, 15 }, + /* 1032 */ { MAD_F(0x05179da4) /* 0.318265572 */, 15 }, + /* 1033 */ { MAD_F(0x05194ce1) /* 0.318676834 */, 15 }, + /* 1034 */ { MAD_F(0x051afc42) /* 0.319088229 */, 15 }, + /* 1035 */ { MAD_F(0x051cabc7) /* 0.319499756 */, 15 }, + /* 1036 */ { MAD_F(0x051e5b6f) /* 0.319911417 */, 15 }, + /* 1037 */ { MAD_F(0x05200b3a) /* 0.320323209 */, 15 }, + /* 1038 */ { MAD_F(0x0521bb2a) /* 0.320735134 */, 15 }, + /* 1039 */ { MAD_F(0x05236b3d) /* 0.321147192 */, 15 }, + + /* 1040 */ { MAD_F(0x05251b73) /* 0.321559381 */, 15 }, + /* 1041 */ { MAD_F(0x0526cbcd) /* 0.321971703 */, 15 }, + /* 1042 */ { MAD_F(0x05287c4a) /* 0.322384156 */, 15 }, + /* 1043 */ { MAD_F(0x052a2cea) /* 0.322796742 */, 15 }, + /* 1044 */ { MAD_F(0x052bddae) /* 0.323209460 */, 15 }, + /* 1045 */ { MAD_F(0x052d8e96) /* 0.323622309 */, 15 }, + /* 1046 */ { MAD_F(0x052f3fa1) /* 0.324035290 */, 15 }, + /* 1047 */ { MAD_F(0x0530f0cf) /* 0.324448403 */, 15 }, + /* 1048 */ { MAD_F(0x0532a220) /* 0.324861647 */, 15 }, + /* 1049 */ { MAD_F(0x05345395) /* 0.325275023 */, 15 }, + /* 1050 */ { MAD_F(0x0536052d) /* 0.325688530 */, 15 }, + /* 1051 */ { MAD_F(0x0537b6e8) /* 0.326102168 */, 15 }, + /* 1052 */ { MAD_F(0x053968c6) /* 0.326515938 */, 15 }, + /* 1053 */ { MAD_F(0x053b1ac8) /* 0.326929839 */, 15 }, + /* 1054 */ { MAD_F(0x053ccced) /* 0.327343870 */, 15 }, + /* 1055 */ { MAD_F(0x053e7f35) /* 0.327758033 */, 15 }, + + /* 1056 */ { MAD_F(0x054031a0) /* 0.328172327 */, 15 }, + /* 1057 */ { MAD_F(0x0541e42e) /* 0.328586751 */, 15 }, + /* 1058 */ { MAD_F(0x054396df) /* 0.329001306 */, 15 }, + /* 1059 */ { MAD_F(0x054549b4) /* 0.329415992 */, 15 }, + /* 1060 */ { MAD_F(0x0546fcab) /* 0.329830808 */, 15 }, + /* 1061 */ { MAD_F(0x0548afc6) /* 0.330245755 */, 15 }, + /* 1062 */ { MAD_F(0x054a6303) /* 0.330660832 */, 15 }, + /* 1063 */ { MAD_F(0x054c1663) /* 0.331076039 */, 15 }, + /* 1064 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 15 }, + /* 1065 */ { MAD_F(0x054f7d8d) /* 0.331906845 */, 15 }, + /* 1066 */ { MAD_F(0x05513156) /* 0.332322443 */, 15 }, + /* 1067 */ { MAD_F(0x0552e542) /* 0.332738170 */, 15 }, + /* 1068 */ { MAD_F(0x05549951) /* 0.333154028 */, 15 }, + /* 1069 */ { MAD_F(0x05564d83) /* 0.333570016 */, 15 }, + /* 1070 */ { MAD_F(0x055801d8) /* 0.333986133 */, 15 }, + /* 1071 */ { MAD_F(0x0559b64f) /* 0.334402380 */, 15 }, + + /* 1072 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 15 }, + /* 1073 */ { MAD_F(0x055d1fa6) /* 0.335235262 */, 15 }, + /* 1074 */ { MAD_F(0x055ed486) /* 0.335651898 */, 15 }, + /* 1075 */ { MAD_F(0x05608988) /* 0.336068662 */, 15 }, + /* 1076 */ { MAD_F(0x05623ead) /* 0.336485556 */, 15 }, + /* 1077 */ { MAD_F(0x0563f3f5) /* 0.336902579 */, 15 }, + /* 1078 */ { MAD_F(0x0565a960) /* 0.337319732 */, 15 }, + /* 1079 */ { MAD_F(0x05675eed) /* 0.337737013 */, 15 }, + /* 1080 */ { MAD_F(0x0569149c) /* 0.338154423 */, 15 }, + /* 1081 */ { MAD_F(0x056aca6f) /* 0.338571962 */, 15 }, + /* 1082 */ { MAD_F(0x056c8064) /* 0.338989630 */, 15 }, + /* 1083 */ { MAD_F(0x056e367b) /* 0.339407426 */, 15 }, + /* 1084 */ { MAD_F(0x056fecb5) /* 0.339825351 */, 15 }, + /* 1085 */ { MAD_F(0x0571a311) /* 0.340243405 */, 15 }, + /* 1086 */ { MAD_F(0x05735990) /* 0.340661587 */, 15 }, + /* 1087 */ { MAD_F(0x05751032) /* 0.341079898 */, 15 }, + + /* 1088 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 15 }, + /* 1089 */ { MAD_F(0x05787ddc) /* 0.341916903 */, 15 }, + /* 1090 */ { MAD_F(0x057a34e4) /* 0.342335598 */, 15 }, + /* 1091 */ { MAD_F(0x057bec0f) /* 0.342754421 */, 15 }, + /* 1092 */ { MAD_F(0x057da35d) /* 0.343173373 */, 15 }, + /* 1093 */ { MAD_F(0x057f5acc) /* 0.343592452 */, 15 }, + /* 1094 */ { MAD_F(0x0581125e) /* 0.344011659 */, 15 }, + /* 1095 */ { MAD_F(0x0582ca12) /* 0.344430993 */, 15 }, + /* 1096 */ { MAD_F(0x058481e9) /* 0.344850455 */, 15 }, + /* 1097 */ { MAD_F(0x058639e2) /* 0.345270045 */, 15 }, + /* 1098 */ { MAD_F(0x0587f1fd) /* 0.345689763 */, 15 }, + /* 1099 */ { MAD_F(0x0589aa3a) /* 0.346109608 */, 15 }, + /* 1100 */ { MAD_F(0x058b629a) /* 0.346529580 */, 15 }, + /* 1101 */ { MAD_F(0x058d1b1b) /* 0.346949679 */, 15 }, + /* 1102 */ { MAD_F(0x058ed3bf) /* 0.347369906 */, 15 }, + /* 1103 */ { MAD_F(0x05908c85) /* 0.347790260 */, 15 }, + + /* 1104 */ { MAD_F(0x0592456d) /* 0.348210741 */, 15 }, + /* 1105 */ { MAD_F(0x0593fe77) /* 0.348631348 */, 15 }, + /* 1106 */ { MAD_F(0x0595b7a3) /* 0.349052083 */, 15 }, + /* 1107 */ { MAD_F(0x059770f1) /* 0.349472945 */, 15 }, + /* 1108 */ { MAD_F(0x05992a61) /* 0.349893933 */, 15 }, + /* 1109 */ { MAD_F(0x059ae3f3) /* 0.350315048 */, 15 }, + /* 1110 */ { MAD_F(0x059c9da8) /* 0.350736290 */, 15 }, + /* 1111 */ { MAD_F(0x059e577e) /* 0.351157658 */, 15 }, + /* 1112 */ { MAD_F(0x05a01176) /* 0.351579152 */, 15 }, + /* 1113 */ { MAD_F(0x05a1cb90) /* 0.352000773 */, 15 }, + /* 1114 */ { MAD_F(0x05a385cc) /* 0.352422520 */, 15 }, + /* 1115 */ { MAD_F(0x05a5402a) /* 0.352844394 */, 15 }, + /* 1116 */ { MAD_F(0x05a6faa9) /* 0.353266393 */, 15 }, + /* 1117 */ { MAD_F(0x05a8b54b) /* 0.353688519 */, 15 }, + /* 1118 */ { MAD_F(0x05aa700e) /* 0.354110771 */, 15 }, + /* 1119 */ { MAD_F(0x05ac2af3) /* 0.354533148 */, 15 }, + + /* 1120 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 15 }, + /* 1121 */ { MAD_F(0x05afa123) /* 0.355378281 */, 15 }, + /* 1122 */ { MAD_F(0x05b15c6d) /* 0.355801035 */, 15 }, + /* 1123 */ { MAD_F(0x05b317d9) /* 0.356223916 */, 15 }, + /* 1124 */ { MAD_F(0x05b4d367) /* 0.356646922 */, 15 }, + /* 1125 */ { MAD_F(0x05b68f16) /* 0.357070053 */, 15 }, + /* 1126 */ { MAD_F(0x05b84ae7) /* 0.357493310 */, 15 }, + /* 1127 */ { MAD_F(0x05ba06da) /* 0.357916692 */, 15 }, + /* 1128 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 15 }, + /* 1129 */ { MAD_F(0x05bd7f25) /* 0.358763832 */, 15 }, + /* 1130 */ { MAD_F(0x05bf3b7c) /* 0.359187590 */, 15 }, + /* 1131 */ { MAD_F(0x05c0f7f5) /* 0.359611472 */, 15 }, + /* 1132 */ { MAD_F(0x05c2b490) /* 0.360035480 */, 15 }, + /* 1133 */ { MAD_F(0x05c4714c) /* 0.360459613 */, 15 }, + /* 1134 */ { MAD_F(0x05c62e2a) /* 0.360883870 */, 15 }, + /* 1135 */ { MAD_F(0x05c7eb29) /* 0.361308252 */, 15 }, + + /* 1136 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 15 }, + /* 1137 */ { MAD_F(0x05cb658c) /* 0.362157390 */, 15 }, + /* 1138 */ { MAD_F(0x05cd22ef) /* 0.362582145 */, 15 }, + /* 1139 */ { MAD_F(0x05cee074) /* 0.363007026 */, 15 }, + /* 1140 */ { MAD_F(0x05d09e1b) /* 0.363432030 */, 15 }, + /* 1141 */ { MAD_F(0x05d25be2) /* 0.363857159 */, 15 }, + /* 1142 */ { MAD_F(0x05d419cb) /* 0.364282412 */, 15 }, + /* 1143 */ { MAD_F(0x05d5d7d5) /* 0.364707789 */, 15 }, + /* 1144 */ { MAD_F(0x05d79601) /* 0.365133291 */, 15 }, + /* 1145 */ { MAD_F(0x05d9544e) /* 0.365558916 */, 15 }, + /* 1146 */ { MAD_F(0x05db12bc) /* 0.365984665 */, 15 }, + /* 1147 */ { MAD_F(0x05dcd14c) /* 0.366410538 */, 15 }, + /* 1148 */ { MAD_F(0x05de8ffc) /* 0.366836535 */, 15 }, + /* 1149 */ { MAD_F(0x05e04ece) /* 0.367262655 */, 15 }, + /* 1150 */ { MAD_F(0x05e20dc1) /* 0.367688900 */, 15 }, + /* 1151 */ { MAD_F(0x05e3ccd5) /* 0.368115267 */, 15 }, + + /* 1152 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 15 }, + /* 1153 */ { MAD_F(0x05e74b61) /* 0.368968373 */, 15 }, + /* 1154 */ { MAD_F(0x05e90ad9) /* 0.369395111 */, 15 }, + /* 1155 */ { MAD_F(0x05eaca72) /* 0.369821973 */, 15 }, + /* 1156 */ { MAD_F(0x05ec8a2b) /* 0.370248957 */, 15 }, + /* 1157 */ { MAD_F(0x05ee4a06) /* 0.370676065 */, 15 }, + /* 1158 */ { MAD_F(0x05f00a02) /* 0.371103295 */, 15 }, + /* 1159 */ { MAD_F(0x05f1ca1f) /* 0.371530649 */, 15 }, + /* 1160 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 15 }, + /* 1161 */ { MAD_F(0x05f54abc) /* 0.372385725 */, 15 }, + /* 1162 */ { MAD_F(0x05f70b3c) /* 0.372813448 */, 15 }, + /* 1163 */ { MAD_F(0x05f8cbdc) /* 0.373241292 */, 15 }, + /* 1164 */ { MAD_F(0x05fa8c9e) /* 0.373669260 */, 15 }, + /* 1165 */ { MAD_F(0x05fc4d81) /* 0.374097350 */, 15 }, + /* 1166 */ { MAD_F(0x05fe0e84) /* 0.374525563 */, 15 }, + /* 1167 */ { MAD_F(0x05ffcfa8) /* 0.374953898 */, 15 }, + + /* 1168 */ { MAD_F(0x060190ee) /* 0.375382356 */, 15 }, + /* 1169 */ { MAD_F(0x06035254) /* 0.375810936 */, 15 }, + /* 1170 */ { MAD_F(0x060513da) /* 0.376239638 */, 15 }, + /* 1171 */ { MAD_F(0x0606d582) /* 0.376668462 */, 15 }, + /* 1172 */ { MAD_F(0x0608974a) /* 0.377097408 */, 15 }, + /* 1173 */ { MAD_F(0x060a5934) /* 0.377526476 */, 15 }, + /* 1174 */ { MAD_F(0x060c1b3d) /* 0.377955667 */, 15 }, + /* 1175 */ { MAD_F(0x060ddd68) /* 0.378384979 */, 15 }, + /* 1176 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 15 }, + /* 1177 */ { MAD_F(0x0611621f) /* 0.379243968 */, 15 }, + /* 1178 */ { MAD_F(0x061324ac) /* 0.379673646 */, 15 }, + /* 1179 */ { MAD_F(0x0614e759) /* 0.380103444 */, 15 }, + /* 1180 */ { MAD_F(0x0616aa27) /* 0.380533365 */, 15 }, + /* 1181 */ { MAD_F(0x06186d16) /* 0.380963407 */, 15 }, + /* 1182 */ { MAD_F(0x061a3025) /* 0.381393570 */, 15 }, + /* 1183 */ { MAD_F(0x061bf354) /* 0.381823855 */, 15 }, + + /* 1184 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 15 }, + /* 1185 */ { MAD_F(0x061f7a15) /* 0.382684788 */, 15 }, + /* 1186 */ { MAD_F(0x06213da7) /* 0.383115436 */, 15 }, + /* 1187 */ { MAD_F(0x06230158) /* 0.383546205 */, 15 }, + /* 1188 */ { MAD_F(0x0624c52a) /* 0.383977096 */, 15 }, + /* 1189 */ { MAD_F(0x0626891d) /* 0.384408107 */, 15 }, + /* 1190 */ { MAD_F(0x06284d30) /* 0.384839239 */, 15 }, + /* 1191 */ { MAD_F(0x062a1164) /* 0.385270492 */, 15 }, + /* 1192 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 15 }, + /* 1193 */ { MAD_F(0x062d9a2c) /* 0.386133359 */, 15 }, + /* 1194 */ { MAD_F(0x062f5ec1) /* 0.386564974 */, 15 }, + /* 1195 */ { MAD_F(0x06312376) /* 0.386996709 */, 15 }, + /* 1196 */ { MAD_F(0x0632e84b) /* 0.387428565 */, 15 }, + /* 1197 */ { MAD_F(0x0634ad41) /* 0.387860541 */, 15 }, + /* 1198 */ { MAD_F(0x06367257) /* 0.388292637 */, 15 }, + /* 1199 */ { MAD_F(0x0638378d) /* 0.388724854 */, 15 }, + + /* 1200 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 15 }, + /* 1201 */ { MAD_F(0x063bc25b) /* 0.389589648 */, 15 }, + /* 1202 */ { MAD_F(0x063d87f2) /* 0.390022225 */, 15 }, + /* 1203 */ { MAD_F(0x063f4da9) /* 0.390454922 */, 15 }, + /* 1204 */ { MAD_F(0x06411380) /* 0.390887739 */, 15 }, + /* 1205 */ { MAD_F(0x0642d978) /* 0.391320675 */, 15 }, + /* 1206 */ { MAD_F(0x06449f8f) /* 0.391753732 */, 15 }, + /* 1207 */ { MAD_F(0x064665c7) /* 0.392186908 */, 15 }, + /* 1208 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 15 }, + /* 1209 */ { MAD_F(0x0649f297) /* 0.393053619 */, 15 }, + /* 1210 */ { MAD_F(0x064bb92f) /* 0.393487154 */, 15 }, + /* 1211 */ { MAD_F(0x064d7fe8) /* 0.393920808 */, 15 }, + /* 1212 */ { MAD_F(0x064f46c0) /* 0.394354582 */, 15 }, + /* 1213 */ { MAD_F(0x06510db8) /* 0.394788475 */, 15 }, + /* 1214 */ { MAD_F(0x0652d4d0) /* 0.395222488 */, 15 }, + /* 1215 */ { MAD_F(0x06549c09) /* 0.395656619 */, 15 }, + + /* 1216 */ { MAD_F(0x06566361) /* 0.396090870 */, 15 }, + /* 1217 */ { MAD_F(0x06582ad9) /* 0.396525239 */, 15 }, + /* 1218 */ { MAD_F(0x0659f271) /* 0.396959728 */, 15 }, + /* 1219 */ { MAD_F(0x065bba29) /* 0.397394336 */, 15 }, + /* 1220 */ { MAD_F(0x065d8201) /* 0.397829062 */, 15 }, + /* 1221 */ { MAD_F(0x065f49f9) /* 0.398263907 */, 15 }, + /* 1222 */ { MAD_F(0x06611211) /* 0.398698871 */, 15 }, + /* 1223 */ { MAD_F(0x0662da49) /* 0.399133954 */, 15 }, + /* 1224 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 15 }, + /* 1225 */ { MAD_F(0x06666b17) /* 0.400004475 */, 15 }, + /* 1226 */ { MAD_F(0x066833ae) /* 0.400439913 */, 15 }, + /* 1227 */ { MAD_F(0x0669fc65) /* 0.400875470 */, 15 }, + /* 1228 */ { MAD_F(0x066bc53c) /* 0.401311145 */, 15 }, + /* 1229 */ { MAD_F(0x066d8e32) /* 0.401746938 */, 15 }, + /* 1230 */ { MAD_F(0x066f5748) /* 0.402182850 */, 15 }, + /* 1231 */ { MAD_F(0x0671207e) /* 0.402618879 */, 15 }, + + /* 1232 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 15 }, + /* 1233 */ { MAD_F(0x0674b349) /* 0.403491293 */, 15 }, + /* 1234 */ { MAD_F(0x06767cde) /* 0.403927676 */, 15 }, + /* 1235 */ { MAD_F(0x06784692) /* 0.404364178 */, 15 }, + /* 1236 */ { MAD_F(0x067a1066) /* 0.404800797 */, 15 }, + /* 1237 */ { MAD_F(0x067bda5a) /* 0.405237535 */, 15 }, + /* 1238 */ { MAD_F(0x067da46d) /* 0.405674390 */, 15 }, + /* 1239 */ { MAD_F(0x067f6ea0) /* 0.406111362 */, 15 }, + /* 1240 */ { MAD_F(0x068138f3) /* 0.406548452 */, 15 }, + /* 1241 */ { MAD_F(0x06830365) /* 0.406985660 */, 15 }, + /* 1242 */ { MAD_F(0x0684cdf6) /* 0.407422985 */, 15 }, + /* 1243 */ { MAD_F(0x068698a8) /* 0.407860427 */, 15 }, + /* 1244 */ { MAD_F(0x06886378) /* 0.408297987 */, 15 }, + /* 1245 */ { MAD_F(0x068a2e68) /* 0.408735664 */, 15 }, + /* 1246 */ { MAD_F(0x068bf978) /* 0.409173458 */, 15 }, + /* 1247 */ { MAD_F(0x068dc4a7) /* 0.409611370 */, 15 }, + + /* 1248 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 15 }, + /* 1249 */ { MAD_F(0x06915b63) /* 0.410487544 */, 15 }, + /* 1250 */ { MAD_F(0x069326f0) /* 0.410925806 */, 15 }, + /* 1251 */ { MAD_F(0x0694f29c) /* 0.411364185 */, 15 }, + /* 1252 */ { MAD_F(0x0696be68) /* 0.411802681 */, 15 }, + /* 1253 */ { MAD_F(0x06988a54) /* 0.412241294 */, 15 }, + /* 1254 */ { MAD_F(0x069a565e) /* 0.412680024 */, 15 }, + /* 1255 */ { MAD_F(0x069c2288) /* 0.413118870 */, 15 }, + /* 1256 */ { MAD_F(0x069deed1) /* 0.413557833 */, 15 }, + /* 1257 */ { MAD_F(0x069fbb3a) /* 0.413996912 */, 15 }, + /* 1258 */ { MAD_F(0x06a187c1) /* 0.414436108 */, 15 }, + /* 1259 */ { MAD_F(0x06a35468) /* 0.414875420 */, 15 }, + /* 1260 */ { MAD_F(0x06a5212f) /* 0.415314849 */, 15 }, + /* 1261 */ { MAD_F(0x06a6ee14) /* 0.415754393 */, 15 }, + /* 1262 */ { MAD_F(0x06a8bb18) /* 0.416194054 */, 15 }, + /* 1263 */ { MAD_F(0x06aa883c) /* 0.416633831 */, 15 }, + + /* 1264 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 15 }, + /* 1265 */ { MAD_F(0x06ae22e1) /* 0.417513734 */, 15 }, + /* 1266 */ { MAD_F(0x06aff062) /* 0.417953859 */, 15 }, + /* 1267 */ { MAD_F(0x06b1be03) /* 0.418394100 */, 15 }, + /* 1268 */ { MAD_F(0x06b38bc2) /* 0.418834457 */, 15 }, + /* 1269 */ { MAD_F(0x06b559a1) /* 0.419274929 */, 15 }, + /* 1270 */ { MAD_F(0x06b7279e) /* 0.419715518 */, 15 }, + /* 1271 */ { MAD_F(0x06b8f5bb) /* 0.420156222 */, 15 }, + /* 1272 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 15 }, + /* 1273 */ { MAD_F(0x06bc9251) /* 0.421037977 */, 15 }, + /* 1274 */ { MAD_F(0x06be60cb) /* 0.421479027 */, 15 }, + /* 1275 */ { MAD_F(0x06c02f63) /* 0.421920193 */, 15 }, + /* 1276 */ { MAD_F(0x06c1fe1b) /* 0.422361475 */, 15 }, + /* 1277 */ { MAD_F(0x06c3ccf1) /* 0.422802871 */, 15 }, + /* 1278 */ { MAD_F(0x06c59be7) /* 0.423244383 */, 15 }, + /* 1279 */ { MAD_F(0x06c76afb) /* 0.423686010 */, 15 }, + + /* 1280 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 15 }, + /* 1281 */ { MAD_F(0x06cb0981) /* 0.424569610 */, 15 }, + /* 1282 */ { MAD_F(0x06ccd8f2) /* 0.425011582 */, 15 }, + /* 1283 */ { MAD_F(0x06cea881) /* 0.425453669 */, 15 }, + /* 1284 */ { MAD_F(0x06d07830) /* 0.425895871 */, 15 }, + /* 1285 */ { MAD_F(0x06d247fe) /* 0.426338188 */, 15 }, + /* 1286 */ { MAD_F(0x06d417ea) /* 0.426780620 */, 15 }, + /* 1287 */ { MAD_F(0x06d5e7f5) /* 0.427223166 */, 15 }, + /* 1288 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 15 }, + /* 1289 */ { MAD_F(0x06d98868) /* 0.428108603 */, 15 }, + /* 1290 */ { MAD_F(0x06db58cf) /* 0.428551493 */, 15 }, + /* 1291 */ { MAD_F(0x06dd2955) /* 0.428994497 */, 15 }, + /* 1292 */ { MAD_F(0x06def9fa) /* 0.429437616 */, 15 }, + /* 1293 */ { MAD_F(0x06e0cabe) /* 0.429880849 */, 15 }, + /* 1294 */ { MAD_F(0x06e29ba0) /* 0.430324197 */, 15 }, + /* 1295 */ { MAD_F(0x06e46ca1) /* 0.430767659 */, 15 }, + + /* 1296 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 15 }, + /* 1297 */ { MAD_F(0x06e80efe) /* 0.431654924 */, 15 }, + /* 1298 */ { MAD_F(0x06e9e05b) /* 0.432098728 */, 15 }, + /* 1299 */ { MAD_F(0x06ebb1d6) /* 0.432542647 */, 15 }, + /* 1300 */ { MAD_F(0x06ed8370) /* 0.432986678 */, 15 }, + /* 1301 */ { MAD_F(0x06ef5529) /* 0.433430824 */, 15 }, + /* 1302 */ { MAD_F(0x06f12700) /* 0.433875084 */, 15 }, + /* 1303 */ { MAD_F(0x06f2f8f5) /* 0.434319457 */, 15 }, + /* 1304 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 15 }, + /* 1305 */ { MAD_F(0x06f69d3c) /* 0.435208545 */, 15 }, + /* 1306 */ { MAD_F(0x06f86f8d) /* 0.435653259 */, 15 }, + /* 1307 */ { MAD_F(0x06fa41fd) /* 0.436098087 */, 15 }, + /* 1308 */ { MAD_F(0x06fc148b) /* 0.436543029 */, 15 }, + /* 1309 */ { MAD_F(0x06fde737) /* 0.436988083 */, 15 }, + /* 1310 */ { MAD_F(0x06ffba02) /* 0.437433251 */, 15 }, + /* 1311 */ { MAD_F(0x07018ceb) /* 0.437878533 */, 15 }, + + /* 1312 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 15 }, + /* 1313 */ { MAD_F(0x07053319) /* 0.438769435 */, 15 }, + /* 1314 */ { MAD_F(0x0707065d) /* 0.439215056 */, 15 }, + /* 1315 */ { MAD_F(0x0708d9c0) /* 0.439660790 */, 15 }, + /* 1316 */ { MAD_F(0x070aad41) /* 0.440106636 */, 15 }, + /* 1317 */ { MAD_F(0x070c80e1) /* 0.440552596 */, 15 }, + /* 1318 */ { MAD_F(0x070e549f) /* 0.440998669 */, 15 }, + /* 1319 */ { MAD_F(0x0710287b) /* 0.441444855 */, 15 }, + /* 1320 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 15 }, + /* 1321 */ { MAD_F(0x0713d08d) /* 0.442337564 */, 15 }, + /* 1322 */ { MAD_F(0x0715a4c4) /* 0.442784088 */, 15 }, + /* 1323 */ { MAD_F(0x07177919) /* 0.443230724 */, 15 }, + /* 1324 */ { MAD_F(0x07194d8c) /* 0.443677473 */, 15 }, + /* 1325 */ { MAD_F(0x071b221e) /* 0.444124334 */, 15 }, + /* 1326 */ { MAD_F(0x071cf6ce) /* 0.444571308 */, 15 }, + /* 1327 */ { MAD_F(0x071ecb9b) /* 0.445018394 */, 15 }, + + /* 1328 */ { MAD_F(0x0720a087) /* 0.445465593 */, 15 }, + /* 1329 */ { MAD_F(0x07227591) /* 0.445912903 */, 15 }, + /* 1330 */ { MAD_F(0x07244ab9) /* 0.446360326 */, 15 }, + /* 1331 */ { MAD_F(0x07262000) /* 0.446807861 */, 15 }, + /* 1332 */ { MAD_F(0x0727f564) /* 0.447255509 */, 15 }, + /* 1333 */ { MAD_F(0x0729cae7) /* 0.447703268 */, 15 }, + /* 1334 */ { MAD_F(0x072ba087) /* 0.448151139 */, 15 }, + /* 1335 */ { MAD_F(0x072d7646) /* 0.448599122 */, 15 }, + /* 1336 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 15 }, + /* 1337 */ { MAD_F(0x0731221d) /* 0.449495424 */, 15 }, + /* 1338 */ { MAD_F(0x0732f835) /* 0.449943742 */, 15 }, + /* 1339 */ { MAD_F(0x0734ce6c) /* 0.450392173 */, 15 }, + /* 1340 */ { MAD_F(0x0736a4c1) /* 0.450840715 */, 15 }, + /* 1341 */ { MAD_F(0x07387b33) /* 0.451289368 */, 15 }, + /* 1342 */ { MAD_F(0x073a51c4) /* 0.451738133 */, 15 }, + /* 1343 */ { MAD_F(0x073c2872) /* 0.452187010 */, 15 }, + + /* 1344 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 15 }, + /* 1345 */ { MAD_F(0x073fd628) /* 0.453085097 */, 15 }, + /* 1346 */ { MAD_F(0x0741ad30) /* 0.453534308 */, 15 }, + /* 1347 */ { MAD_F(0x07438456) /* 0.453983630 */, 15 }, + /* 1348 */ { MAD_F(0x07455b9a) /* 0.454433063 */, 15 }, + /* 1349 */ { MAD_F(0x074732fc) /* 0.454882607 */, 15 }, + /* 1350 */ { MAD_F(0x07490a7b) /* 0.455332262 */, 15 }, + /* 1351 */ { MAD_F(0x074ae218) /* 0.455782029 */, 15 }, + /* 1352 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 15 }, + /* 1353 */ { MAD_F(0x074e91ac) /* 0.456681894 */, 15 }, + /* 1354 */ { MAD_F(0x075069a3) /* 0.457131993 */, 15 }, + /* 1355 */ { MAD_F(0x075241b7) /* 0.457582203 */, 15 }, + /* 1356 */ { MAD_F(0x075419e9) /* 0.458032524 */, 15 }, + /* 1357 */ { MAD_F(0x0755f239) /* 0.458482956 */, 15 }, + /* 1358 */ { MAD_F(0x0757caa7) /* 0.458933498 */, 15 }, + /* 1359 */ { MAD_F(0x0759a332) /* 0.459384151 */, 15 }, + + /* 1360 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 15 }, + /* 1361 */ { MAD_F(0x075d54a1) /* 0.460285788 */, 15 }, + /* 1362 */ { MAD_F(0x075f2d85) /* 0.460736772 */, 15 }, + /* 1363 */ { MAD_F(0x07610687) /* 0.461187867 */, 15 }, + /* 1364 */ { MAD_F(0x0762dfa6) /* 0.461639071 */, 15 }, + /* 1365 */ { MAD_F(0x0764b8e3) /* 0.462090387 */, 15 }, + /* 1366 */ { MAD_F(0x0766923e) /* 0.462541812 */, 15 }, + /* 1367 */ { MAD_F(0x07686bb6) /* 0.462993348 */, 15 }, + /* 1368 */ { MAD_F(0x076a454c) /* 0.463444993 */, 15 }, + /* 1369 */ { MAD_F(0x076c1eff) /* 0.463896749 */, 15 }, + /* 1370 */ { MAD_F(0x076df8d0) /* 0.464348615 */, 15 }, + /* 1371 */ { MAD_F(0x076fd2be) /* 0.464800591 */, 15 }, + /* 1372 */ { MAD_F(0x0771acca) /* 0.465252676 */, 15 }, + /* 1373 */ { MAD_F(0x077386f3) /* 0.465704872 */, 15 }, + /* 1374 */ { MAD_F(0x0775613a) /* 0.466157177 */, 15 }, + /* 1375 */ { MAD_F(0x07773b9e) /* 0.466609592 */, 15 }, + + /* 1376 */ { MAD_F(0x07791620) /* 0.467062117 */, 15 }, + /* 1377 */ { MAD_F(0x077af0bf) /* 0.467514751 */, 15 }, + /* 1378 */ { MAD_F(0x077ccb7c) /* 0.467967495 */, 15 }, + /* 1379 */ { MAD_F(0x077ea656) /* 0.468420349 */, 15 }, + /* 1380 */ { MAD_F(0x0780814d) /* 0.468873312 */, 15 }, + /* 1381 */ { MAD_F(0x07825c62) /* 0.469326384 */, 15 }, + /* 1382 */ { MAD_F(0x07843794) /* 0.469779566 */, 15 }, + /* 1383 */ { MAD_F(0x078612e3) /* 0.470232857 */, 15 }, + /* 1384 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 15 }, + /* 1385 */ { MAD_F(0x0789c9da) /* 0.471139767 */, 15 }, + /* 1386 */ { MAD_F(0x078ba581) /* 0.471593386 */, 15 }, + /* 1387 */ { MAD_F(0x078d8146) /* 0.472047114 */, 15 }, + /* 1388 */ { MAD_F(0x078f5d28) /* 0.472500951 */, 15 }, + /* 1389 */ { MAD_F(0x07913927) /* 0.472954896 */, 15 }, + /* 1390 */ { MAD_F(0x07931543) /* 0.473408951 */, 15 }, + /* 1391 */ { MAD_F(0x0794f17d) /* 0.473863115 */, 15 }, + + /* 1392 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 15 }, + /* 1393 */ { MAD_F(0x0798aa48) /* 0.474771769 */, 15 }, + /* 1394 */ { MAD_F(0x079a86d9) /* 0.475226259 */, 15 }, + /* 1395 */ { MAD_F(0x079c6388) /* 0.475680858 */, 15 }, + /* 1396 */ { MAD_F(0x079e4053) /* 0.476135565 */, 15 }, + /* 1397 */ { MAD_F(0x07a01d3c) /* 0.476590381 */, 15 }, + /* 1398 */ { MAD_F(0x07a1fa42) /* 0.477045306 */, 15 }, + /* 1399 */ { MAD_F(0x07a3d765) /* 0.477500339 */, 15 }, + /* 1400 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 15 }, + /* 1401 */ { MAD_F(0x07a79202) /* 0.478410731 */, 15 }, + /* 1402 */ { MAD_F(0x07a96f7d) /* 0.478866089 */, 15 }, + /* 1403 */ { MAD_F(0x07ab4d14) /* 0.479321555 */, 15 }, + /* 1404 */ { MAD_F(0x07ad2ac8) /* 0.479777130 */, 15 }, + /* 1405 */ { MAD_F(0x07af089a) /* 0.480232813 */, 15 }, + /* 1406 */ { MAD_F(0x07b0e688) /* 0.480688604 */, 15 }, + /* 1407 */ { MAD_F(0x07b2c494) /* 0.481144503 */, 15 }, + + /* 1408 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 15 }, + /* 1409 */ { MAD_F(0x07b68102) /* 0.482056625 */, 15 }, + /* 1410 */ { MAD_F(0x07b85f64) /* 0.482512848 */, 15 }, + /* 1411 */ { MAD_F(0x07ba3de4) /* 0.482969179 */, 15 }, + /* 1412 */ { MAD_F(0x07bc1c80) /* 0.483425618 */, 15 }, + /* 1413 */ { MAD_F(0x07bdfb39) /* 0.483882164 */, 15 }, + /* 1414 */ { MAD_F(0x07bfda0f) /* 0.484338818 */, 15 }, + /* 1415 */ { MAD_F(0x07c1b902) /* 0.484795580 */, 15 }, + /* 1416 */ { MAD_F(0x07c39812) /* 0.485252449 */, 15 }, + /* 1417 */ { MAD_F(0x07c5773f) /* 0.485709426 */, 15 }, + /* 1418 */ { MAD_F(0x07c75689) /* 0.486166511 */, 15 }, + /* 1419 */ { MAD_F(0x07c935ef) /* 0.486623703 */, 15 }, + /* 1420 */ { MAD_F(0x07cb1573) /* 0.487081002 */, 15 }, + /* 1421 */ { MAD_F(0x07ccf513) /* 0.487538409 */, 15 }, + /* 1422 */ { MAD_F(0x07ced4d0) /* 0.487995923 */, 15 }, + /* 1423 */ { MAD_F(0x07d0b4aa) /* 0.488453544 */, 15 }, + + /* 1424 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 15 }, + /* 1425 */ { MAD_F(0x07d474b3) /* 0.489369108 */, 15 }, + /* 1426 */ { MAD_F(0x07d654e4) /* 0.489827051 */, 15 }, + /* 1427 */ { MAD_F(0x07d83530) /* 0.490285101 */, 15 }, + /* 1428 */ { MAD_F(0x07da159a) /* 0.490743258 */, 15 }, + /* 1429 */ { MAD_F(0x07dbf620) /* 0.491201522 */, 15 }, + /* 1430 */ { MAD_F(0x07ddd6c3) /* 0.491659892 */, 15 }, + /* 1431 */ { MAD_F(0x07dfb783) /* 0.492118370 */, 15 }, + /* 1432 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 15 }, + /* 1433 */ { MAD_F(0x07e37958) /* 0.493035645 */, 15 }, + /* 1434 */ { MAD_F(0x07e55a6e) /* 0.493494443 */, 15 }, + /* 1435 */ { MAD_F(0x07e73ba0) /* 0.493953348 */, 15 }, + /* 1436 */ { MAD_F(0x07e91cef) /* 0.494412359 */, 15 }, + /* 1437 */ { MAD_F(0x07eafe5a) /* 0.494871476 */, 15 }, + /* 1438 */ { MAD_F(0x07ecdfe2) /* 0.495330701 */, 15 }, + /* 1439 */ { MAD_F(0x07eec187) /* 0.495790031 */, 15 }, + + /* 1440 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 15 }, + /* 1441 */ { MAD_F(0x07f28526) /* 0.496709012 */, 15 }, + /* 1442 */ { MAD_F(0x07f46720) /* 0.497168662 */, 15 }, + /* 1443 */ { MAD_F(0x07f64937) /* 0.497628418 */, 15 }, + /* 1444 */ { MAD_F(0x07f82b6a) /* 0.498088280 */, 15 }, + /* 1445 */ { MAD_F(0x07fa0dba) /* 0.498548248 */, 15 }, + /* 1446 */ { MAD_F(0x07fbf026) /* 0.499008323 */, 15 }, + /* 1447 */ { MAD_F(0x07fdd2af) /* 0.499468503 */, 15 }, + /* 1448 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 15 }, + /* 1449 */ { MAD_F(0x0400cc0b) /* 0.250194591 */, 16 }, + /* 1450 */ { MAD_F(0x0401bd7a) /* 0.250424840 */, 16 }, + /* 1451 */ { MAD_F(0x0402aef7) /* 0.250655143 */, 16 }, + /* 1452 */ { MAD_F(0x0403a083) /* 0.250885498 */, 16 }, + /* 1453 */ { MAD_F(0x0404921c) /* 0.251115906 */, 16 }, + /* 1454 */ { MAD_F(0x040583c4) /* 0.251346367 */, 16 }, + /* 1455 */ { MAD_F(0x0406757a) /* 0.251576880 */, 16 }, + + /* 1456 */ { MAD_F(0x0407673f) /* 0.251807447 */, 16 }, + /* 1457 */ { MAD_F(0x04085911) /* 0.252038066 */, 16 }, + /* 1458 */ { MAD_F(0x04094af1) /* 0.252268738 */, 16 }, + /* 1459 */ { MAD_F(0x040a3ce0) /* 0.252499463 */, 16 }, + /* 1460 */ { MAD_F(0x040b2edd) /* 0.252730240 */, 16 }, + /* 1461 */ { MAD_F(0x040c20e8) /* 0.252961071 */, 16 }, + /* 1462 */ { MAD_F(0x040d1301) /* 0.253191953 */, 16 }, + /* 1463 */ { MAD_F(0x040e0529) /* 0.253422889 */, 16 }, + /* 1464 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 16 }, + /* 1465 */ { MAD_F(0x040fe9a1) /* 0.253884918 */, 16 }, + /* 1466 */ { MAD_F(0x0410dbf3) /* 0.254116011 */, 16 }, + /* 1467 */ { MAD_F(0x0411ce53) /* 0.254347157 */, 16 }, + /* 1468 */ { MAD_F(0x0412c0c1) /* 0.254578356 */, 16 }, + /* 1469 */ { MAD_F(0x0413b33d) /* 0.254809606 */, 16 }, + /* 1470 */ { MAD_F(0x0414a5c7) /* 0.255040910 */, 16 }, + /* 1471 */ { MAD_F(0x0415985f) /* 0.255272266 */, 16 }, + + /* 1472 */ { MAD_F(0x04168b05) /* 0.255503674 */, 16 }, + /* 1473 */ { MAD_F(0x04177db9) /* 0.255735135 */, 16 }, + /* 1474 */ { MAD_F(0x0418707c) /* 0.255966648 */, 16 }, + /* 1475 */ { MAD_F(0x0419634c) /* 0.256198213 */, 16 }, + /* 1476 */ { MAD_F(0x041a562a) /* 0.256429831 */, 16 }, + /* 1477 */ { MAD_F(0x041b4917) /* 0.256661501 */, 16 }, + /* 1478 */ { MAD_F(0x041c3c11) /* 0.256893223 */, 16 }, + /* 1479 */ { MAD_F(0x041d2f1a) /* 0.257124998 */, 16 }, + /* 1480 */ { MAD_F(0x041e2230) /* 0.257356825 */, 16 }, + /* 1481 */ { MAD_F(0x041f1555) /* 0.257588704 */, 16 }, + /* 1482 */ { MAD_F(0x04200888) /* 0.257820635 */, 16 }, + /* 1483 */ { MAD_F(0x0420fbc8) /* 0.258052619 */, 16 }, + /* 1484 */ { MAD_F(0x0421ef17) /* 0.258284654 */, 16 }, + /* 1485 */ { MAD_F(0x0422e273) /* 0.258516742 */, 16 }, + /* 1486 */ { MAD_F(0x0423d5de) /* 0.258748882 */, 16 }, + /* 1487 */ { MAD_F(0x0424c956) /* 0.258981074 */, 16 }, + + /* 1488 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 16 }, + /* 1489 */ { MAD_F(0x0426b071) /* 0.259445614 */, 16 }, + /* 1490 */ { MAD_F(0x0427a414) /* 0.259677962 */, 16 }, + /* 1491 */ { MAD_F(0x042897c4) /* 0.259910362 */, 16 }, + /* 1492 */ { MAD_F(0x04298b83) /* 0.260142814 */, 16 }, + /* 1493 */ { MAD_F(0x042a7f4f) /* 0.260375318 */, 16 }, + /* 1494 */ { MAD_F(0x042b7329) /* 0.260607874 */, 16 }, + /* 1495 */ { MAD_F(0x042c6711) /* 0.260840481 */, 16 }, + /* 1496 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 16 }, + /* 1497 */ { MAD_F(0x042e4f0b) /* 0.261305852 */, 16 }, + /* 1498 */ { MAD_F(0x042f431d) /* 0.261538616 */, 16 }, + /* 1499 */ { MAD_F(0x0430373d) /* 0.261771431 */, 16 }, + /* 1500 */ { MAD_F(0x04312b6b) /* 0.262004297 */, 16 }, + /* 1501 */ { MAD_F(0x04321fa6) /* 0.262237216 */, 16 }, + /* 1502 */ { MAD_F(0x043313f0) /* 0.262470186 */, 16 }, + /* 1503 */ { MAD_F(0x04340847) /* 0.262703208 */, 16 }, + + /* 1504 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 16 }, + /* 1505 */ { MAD_F(0x0435f120) /* 0.263169407 */, 16 }, + /* 1506 */ { MAD_F(0x0436e5a1) /* 0.263402584 */, 16 }, + /* 1507 */ { MAD_F(0x0437da2f) /* 0.263635813 */, 16 }, + /* 1508 */ { MAD_F(0x0438cecc) /* 0.263869093 */, 16 }, + /* 1509 */ { MAD_F(0x0439c377) /* 0.264102425 */, 16 }, + /* 1510 */ { MAD_F(0x043ab82f) /* 0.264335808 */, 16 }, + /* 1511 */ { MAD_F(0x043bacf5) /* 0.264569243 */, 16 }, + /* 1512 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 16 }, + /* 1513 */ { MAD_F(0x043d96ab) /* 0.265036267 */, 16 }, + /* 1514 */ { MAD_F(0x043e8b9b) /* 0.265269857 */, 16 }, + /* 1515 */ { MAD_F(0x043f8098) /* 0.265503498 */, 16 }, + /* 1516 */ { MAD_F(0x044075a3) /* 0.265737190 */, 16 }, + /* 1517 */ { MAD_F(0x04416abc) /* 0.265970933 */, 16 }, + /* 1518 */ { MAD_F(0x04425fe3) /* 0.266204728 */, 16 }, + /* 1519 */ { MAD_F(0x04435518) /* 0.266438574 */, 16 }, + + /* 1520 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 16 }, + /* 1521 */ { MAD_F(0x04453fab) /* 0.266906421 */, 16 }, + /* 1522 */ { MAD_F(0x04463508) /* 0.267140421 */, 16 }, + /* 1523 */ { MAD_F(0x04472a74) /* 0.267374472 */, 16 }, + /* 1524 */ { MAD_F(0x04481fee) /* 0.267608575 */, 16 }, + /* 1525 */ { MAD_F(0x04491575) /* 0.267842729 */, 16 }, + /* 1526 */ { MAD_F(0x044a0b0a) /* 0.268076934 */, 16 }, + /* 1527 */ { MAD_F(0x044b00ac) /* 0.268311190 */, 16 }, + /* 1528 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 16 }, + /* 1529 */ { MAD_F(0x044cec1b) /* 0.268779856 */, 16 }, + /* 1530 */ { MAD_F(0x044de1e7) /* 0.269014265 */, 16 }, + /* 1531 */ { MAD_F(0x044ed7c0) /* 0.269248726 */, 16 }, + /* 1532 */ { MAD_F(0x044fcda8) /* 0.269483238 */, 16 }, + /* 1533 */ { MAD_F(0x0450c39c) /* 0.269717800 */, 16 }, + /* 1534 */ { MAD_F(0x0451b99f) /* 0.269952414 */, 16 }, + /* 1535 */ { MAD_F(0x0452afaf) /* 0.270187079 */, 16 }, + + /* 1536 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 16 }, + /* 1537 */ { MAD_F(0x04549bf9) /* 0.270656561 */, 16 }, + /* 1538 */ { MAD_F(0x04559232) /* 0.270891379 */, 16 }, + /* 1539 */ { MAD_F(0x04568879) /* 0.271126247 */, 16 }, + /* 1540 */ { MAD_F(0x04577ece) /* 0.271361166 */, 16 }, + /* 1541 */ { MAD_F(0x04587530) /* 0.271596136 */, 16 }, + /* 1542 */ { MAD_F(0x04596ba0) /* 0.271831157 */, 16 }, + /* 1543 */ { MAD_F(0x045a621e) /* 0.272066229 */, 16 }, + /* 1544 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 16 }, + /* 1545 */ { MAD_F(0x045c4f42) /* 0.272536525 */, 16 }, + /* 1546 */ { MAD_F(0x045d45e9) /* 0.272771749 */, 16 }, + /* 1547 */ { MAD_F(0x045e3c9d) /* 0.273007024 */, 16 }, + /* 1548 */ { MAD_F(0x045f335e) /* 0.273242350 */, 16 }, + /* 1549 */ { MAD_F(0x04602a2e) /* 0.273477726 */, 16 }, + /* 1550 */ { MAD_F(0x0461210b) /* 0.273713153 */, 16 }, + /* 1551 */ { MAD_F(0x046217f5) /* 0.273948630 */, 16 }, + + /* 1552 */ { MAD_F(0x04630eed) /* 0.274184158 */, 16 }, + /* 1553 */ { MAD_F(0x046405f3) /* 0.274419737 */, 16 }, + /* 1554 */ { MAD_F(0x0464fd06) /* 0.274655366 */, 16 }, + /* 1555 */ { MAD_F(0x0465f427) /* 0.274891046 */, 16 }, + /* 1556 */ { MAD_F(0x0466eb55) /* 0.275126776 */, 16 }, + /* 1557 */ { MAD_F(0x0467e291) /* 0.275362557 */, 16 }, + /* 1558 */ { MAD_F(0x0468d9db) /* 0.275598389 */, 16 }, + /* 1559 */ { MAD_F(0x0469d132) /* 0.275834270 */, 16 }, + /* 1560 */ { MAD_F(0x046ac896) /* 0.276070203 */, 16 }, + /* 1561 */ { MAD_F(0x046bc009) /* 0.276306185 */, 16 }, + /* 1562 */ { MAD_F(0x046cb788) /* 0.276542218 */, 16 }, + /* 1563 */ { MAD_F(0x046daf15) /* 0.276778302 */, 16 }, + /* 1564 */ { MAD_F(0x046ea6b0) /* 0.277014435 */, 16 }, + /* 1565 */ { MAD_F(0x046f9e58) /* 0.277250619 */, 16 }, + /* 1566 */ { MAD_F(0x0470960e) /* 0.277486854 */, 16 }, + /* 1567 */ { MAD_F(0x04718dd1) /* 0.277723139 */, 16 }, + + /* 1568 */ { MAD_F(0x047285a2) /* 0.277959474 */, 16 }, + /* 1569 */ { MAD_F(0x04737d80) /* 0.278195859 */, 16 }, + /* 1570 */ { MAD_F(0x0474756c) /* 0.278432294 */, 16 }, + /* 1571 */ { MAD_F(0x04756d65) /* 0.278668780 */, 16 }, + /* 1572 */ { MAD_F(0x0476656b) /* 0.278905316 */, 16 }, + /* 1573 */ { MAD_F(0x04775d7f) /* 0.279141902 */, 16 }, + /* 1574 */ { MAD_F(0x047855a1) /* 0.279378538 */, 16 }, + /* 1575 */ { MAD_F(0x04794dd0) /* 0.279615224 */, 16 }, + /* 1576 */ { MAD_F(0x047a460c) /* 0.279851960 */, 16 }, + /* 1577 */ { MAD_F(0x047b3e56) /* 0.280088747 */, 16 }, + /* 1578 */ { MAD_F(0x047c36ae) /* 0.280325583 */, 16 }, + /* 1579 */ { MAD_F(0x047d2f12) /* 0.280562470 */, 16 }, + /* 1580 */ { MAD_F(0x047e2784) /* 0.280799406 */, 16 }, + /* 1581 */ { MAD_F(0x047f2004) /* 0.281036393 */, 16 }, + /* 1582 */ { MAD_F(0x04801891) /* 0.281273429 */, 16 }, + /* 1583 */ { MAD_F(0x0481112b) /* 0.281510516 */, 16 }, + + /* 1584 */ { MAD_F(0x048209d3) /* 0.281747652 */, 16 }, + /* 1585 */ { MAD_F(0x04830288) /* 0.281984838 */, 16 }, + /* 1586 */ { MAD_F(0x0483fb4b) /* 0.282222075 */, 16 }, + /* 1587 */ { MAD_F(0x0484f41b) /* 0.282459361 */, 16 }, + /* 1588 */ { MAD_F(0x0485ecf8) /* 0.282696697 */, 16 }, + /* 1589 */ { MAD_F(0x0486e5e3) /* 0.282934082 */, 16 }, + /* 1590 */ { MAD_F(0x0487dedb) /* 0.283171518 */, 16 }, + /* 1591 */ { MAD_F(0x0488d7e1) /* 0.283409003 */, 16 }, + /* 1592 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 16 }, + /* 1593 */ { MAD_F(0x048aca14) /* 0.283884123 */, 16 }, + /* 1594 */ { MAD_F(0x048bc341) /* 0.284121757 */, 16 }, + /* 1595 */ { MAD_F(0x048cbc7c) /* 0.284359441 */, 16 }, + /* 1596 */ { MAD_F(0x048db5c4) /* 0.284597175 */, 16 }, + /* 1597 */ { MAD_F(0x048eaf1a) /* 0.284834959 */, 16 }, + /* 1598 */ { MAD_F(0x048fa87d) /* 0.285072792 */, 16 }, + /* 1599 */ { MAD_F(0x0490a1ed) /* 0.285310675 */, 16 }, + + /* 1600 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 16 }, + /* 1601 */ { MAD_F(0x049294f5) /* 0.285786589 */, 16 }, + /* 1602 */ { MAD_F(0x04938e8d) /* 0.286024621 */, 16 }, + /* 1603 */ { MAD_F(0x04948833) /* 0.286262702 */, 16 }, + /* 1604 */ { MAD_F(0x049581e5) /* 0.286500832 */, 16 }, + /* 1605 */ { MAD_F(0x04967ba5) /* 0.286739012 */, 16 }, + /* 1606 */ { MAD_F(0x04977573) /* 0.286977242 */, 16 }, + /* 1607 */ { MAD_F(0x04986f4d) /* 0.287215521 */, 16 }, + /* 1608 */ { MAD_F(0x04996935) /* 0.287453849 */, 16 }, + /* 1609 */ { MAD_F(0x049a632a) /* 0.287692227 */, 16 }, + /* 1610 */ { MAD_F(0x049b5d2c) /* 0.287930654 */, 16 }, + /* 1611 */ { MAD_F(0x049c573c) /* 0.288169131 */, 16 }, + /* 1612 */ { MAD_F(0x049d5159) /* 0.288407657 */, 16 }, + /* 1613 */ { MAD_F(0x049e4b83) /* 0.288646232 */, 16 }, + /* 1614 */ { MAD_F(0x049f45ba) /* 0.288884857 */, 16 }, + /* 1615 */ { MAD_F(0x04a03ffe) /* 0.289123530 */, 16 }, + + /* 1616 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 16 }, + /* 1617 */ { MAD_F(0x04a234af) /* 0.289601026 */, 16 }, + /* 1618 */ { MAD_F(0x04a32f1b) /* 0.289839847 */, 16 }, + /* 1619 */ { MAD_F(0x04a42995) /* 0.290078718 */, 16 }, + /* 1620 */ { MAD_F(0x04a5241b) /* 0.290317638 */, 16 }, + /* 1621 */ { MAD_F(0x04a61eaf) /* 0.290556607 */, 16 }, + /* 1622 */ { MAD_F(0x04a71950) /* 0.290795626 */, 16 }, + /* 1623 */ { MAD_F(0x04a813fe) /* 0.291034693 */, 16 }, + /* 1624 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 16 }, + /* 1625 */ { MAD_F(0x04aa0982) /* 0.291512975 */, 16 }, + /* 1626 */ { MAD_F(0x04ab0458) /* 0.291752190 */, 16 }, + /* 1627 */ { MAD_F(0x04abff3b) /* 0.291991453 */, 16 }, + /* 1628 */ { MAD_F(0x04acfa2b) /* 0.292230766 */, 16 }, + /* 1629 */ { MAD_F(0x04adf528) /* 0.292470128 */, 16 }, + /* 1630 */ { MAD_F(0x04aef032) /* 0.292709539 */, 16 }, + /* 1631 */ { MAD_F(0x04afeb4a) /* 0.292948998 */, 16 }, + + /* 1632 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 16 }, + /* 1633 */ { MAD_F(0x04b1e1a0) /* 0.293428065 */, 16 }, + /* 1634 */ { MAD_F(0x04b2dcdf) /* 0.293667671 */, 16 }, + /* 1635 */ { MAD_F(0x04b3d82b) /* 0.293907326 */, 16 }, + /* 1636 */ { MAD_F(0x04b4d384) /* 0.294147031 */, 16 }, + /* 1637 */ { MAD_F(0x04b5ceea) /* 0.294386784 */, 16 }, + /* 1638 */ { MAD_F(0x04b6ca5e) /* 0.294626585 */, 16 }, + /* 1639 */ { MAD_F(0x04b7c5de) /* 0.294866436 */, 16 }, + /* 1640 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 16 }, + /* 1641 */ { MAD_F(0x04b9bd06) /* 0.295346284 */, 16 }, + /* 1642 */ { MAD_F(0x04bab8ae) /* 0.295586281 */, 16 }, + /* 1643 */ { MAD_F(0x04bbb463) /* 0.295826327 */, 16 }, + /* 1644 */ { MAD_F(0x04bcb024) /* 0.296066421 */, 16 }, + /* 1645 */ { MAD_F(0x04bdabf3) /* 0.296306564 */, 16 }, + /* 1646 */ { MAD_F(0x04bea7cf) /* 0.296546756 */, 16 }, + /* 1647 */ { MAD_F(0x04bfa3b8) /* 0.296786996 */, 16 }, + + /* 1648 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 16 }, + /* 1649 */ { MAD_F(0x04c19bb2) /* 0.297267623 */, 16 }, + /* 1650 */ { MAD_F(0x04c297c2) /* 0.297508009 */, 16 }, + /* 1651 */ { MAD_F(0x04c393df) /* 0.297748444 */, 16 }, + /* 1652 */ { MAD_F(0x04c49009) /* 0.297988927 */, 16 }, + /* 1653 */ { MAD_F(0x04c58c41) /* 0.298229459 */, 16 }, + /* 1654 */ { MAD_F(0x04c68885) /* 0.298470039 */, 16 }, + /* 1655 */ { MAD_F(0x04c784d6) /* 0.298710668 */, 16 }, + /* 1656 */ { MAD_F(0x04c88135) /* 0.298951346 */, 16 }, + /* 1657 */ { MAD_F(0x04c97da0) /* 0.299192071 */, 16 }, + /* 1658 */ { MAD_F(0x04ca7a18) /* 0.299432846 */, 16 }, + /* 1659 */ { MAD_F(0x04cb769e) /* 0.299673668 */, 16 }, + /* 1660 */ { MAD_F(0x04cc7330) /* 0.299914539 */, 16 }, + /* 1661 */ { MAD_F(0x04cd6fcf) /* 0.300155459 */, 16 }, + /* 1662 */ { MAD_F(0x04ce6c7b) /* 0.300396426 */, 16 }, + /* 1663 */ { MAD_F(0x04cf6935) /* 0.300637443 */, 16 }, + + /* 1664 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 16 }, + /* 1665 */ { MAD_F(0x04d162ce) /* 0.301119620 */, 16 }, + /* 1666 */ { MAD_F(0x04d25fae) /* 0.301360781 */, 16 }, + /* 1667 */ { MAD_F(0x04d35c9b) /* 0.301601990 */, 16 }, + /* 1668 */ { MAD_F(0x04d45995) /* 0.301843247 */, 16 }, + /* 1669 */ { MAD_F(0x04d5569c) /* 0.302084553 */, 16 }, + /* 1670 */ { MAD_F(0x04d653b0) /* 0.302325907 */, 16 }, + /* 1671 */ { MAD_F(0x04d750d1) /* 0.302567309 */, 16 }, + /* 1672 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 16 }, + /* 1673 */ { MAD_F(0x04d94b3a) /* 0.303050257 */, 16 }, + /* 1674 */ { MAD_F(0x04da4881) /* 0.303291804 */, 16 }, + /* 1675 */ { MAD_F(0x04db45d6) /* 0.303533399 */, 16 }, + /* 1676 */ { MAD_F(0x04dc4337) /* 0.303775041 */, 16 }, + /* 1677 */ { MAD_F(0x04dd40a6) /* 0.304016732 */, 16 }, + /* 1678 */ { MAD_F(0x04de3e21) /* 0.304258471 */, 16 }, + /* 1679 */ { MAD_F(0x04df3ba9) /* 0.304500257 */, 16 }, + + /* 1680 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 16 }, + /* 1681 */ { MAD_F(0x04e136e0) /* 0.304983975 */, 16 }, + /* 1682 */ { MAD_F(0x04e2348f) /* 0.305225906 */, 16 }, + /* 1683 */ { MAD_F(0x04e3324b) /* 0.305467885 */, 16 }, + /* 1684 */ { MAD_F(0x04e43013) /* 0.305709911 */, 16 }, + /* 1685 */ { MAD_F(0x04e52de9) /* 0.305951986 */, 16 }, + /* 1686 */ { MAD_F(0x04e62bcb) /* 0.306194108 */, 16 }, + /* 1687 */ { MAD_F(0x04e729ba) /* 0.306436279 */, 16 }, + /* 1688 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 16 }, + /* 1689 */ { MAD_F(0x04e925bf) /* 0.306920763 */, 16 }, + /* 1690 */ { MAD_F(0x04ea23d4) /* 0.307163077 */, 16 }, + /* 1691 */ { MAD_F(0x04eb21f7) /* 0.307405438 */, 16 }, + /* 1692 */ { MAD_F(0x04ec2026) /* 0.307647848 */, 16 }, + /* 1693 */ { MAD_F(0x04ed1e62) /* 0.307890305 */, 16 }, + /* 1694 */ { MAD_F(0x04ee1cab) /* 0.308132810 */, 16 }, + /* 1695 */ { MAD_F(0x04ef1b01) /* 0.308375362 */, 16 }, + + /* 1696 */ { MAD_F(0x04f01963) /* 0.308617963 */, 16 }, + /* 1697 */ { MAD_F(0x04f117d3) /* 0.308860611 */, 16 }, + /* 1698 */ { MAD_F(0x04f2164f) /* 0.309103306 */, 16 }, + /* 1699 */ { MAD_F(0x04f314d8) /* 0.309346050 */, 16 }, + /* 1700 */ { MAD_F(0x04f4136d) /* 0.309588841 */, 16 }, + /* 1701 */ { MAD_F(0x04f51210) /* 0.309831679 */, 16 }, + /* 1702 */ { MAD_F(0x04f610bf) /* 0.310074565 */, 16 }, + /* 1703 */ { MAD_F(0x04f70f7b) /* 0.310317499 */, 16 }, + /* 1704 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 16 }, + /* 1705 */ { MAD_F(0x04f90d19) /* 0.310803509 */, 16 }, + /* 1706 */ { MAD_F(0x04fa0bfc) /* 0.311046586 */, 16 }, + /* 1707 */ { MAD_F(0x04fb0aeb) /* 0.311289710 */, 16 }, + /* 1708 */ { MAD_F(0x04fc09e7) /* 0.311532881 */, 16 }, + /* 1709 */ { MAD_F(0x04fd08ef) /* 0.311776100 */, 16 }, + /* 1710 */ { MAD_F(0x04fe0805) /* 0.312019366 */, 16 }, + /* 1711 */ { MAD_F(0x04ff0727) /* 0.312262680 */, 16 }, + + /* 1712 */ { MAD_F(0x05000655) /* 0.312506041 */, 16 }, + /* 1713 */ { MAD_F(0x05010591) /* 0.312749449 */, 16 }, + /* 1714 */ { MAD_F(0x050204d9) /* 0.312992905 */, 16 }, + /* 1715 */ { MAD_F(0x0503042e) /* 0.313236408 */, 16 }, + /* 1716 */ { MAD_F(0x0504038f) /* 0.313479959 */, 16 }, + /* 1717 */ { MAD_F(0x050502fe) /* 0.313723556 */, 16 }, + /* 1718 */ { MAD_F(0x05060279) /* 0.313967202 */, 16 }, + /* 1719 */ { MAD_F(0x05070200) /* 0.314210894 */, 16 }, + /* 1720 */ { MAD_F(0x05080195) /* 0.314454634 */, 16 }, + /* 1721 */ { MAD_F(0x05090136) /* 0.314698420 */, 16 }, + /* 1722 */ { MAD_F(0x050a00e3) /* 0.314942255 */, 16 }, + /* 1723 */ { MAD_F(0x050b009e) /* 0.315186136 */, 16 }, + /* 1724 */ { MAD_F(0x050c0065) /* 0.315430064 */, 16 }, + /* 1725 */ { MAD_F(0x050d0039) /* 0.315674040 */, 16 }, + /* 1726 */ { MAD_F(0x050e0019) /* 0.315918063 */, 16 }, + /* 1727 */ { MAD_F(0x050f0006) /* 0.316162133 */, 16 }, + + /* 1728 */ { MAD_F(0x05100000) /* 0.316406250 */, 16 }, + /* 1729 */ { MAD_F(0x05110006) /* 0.316650414 */, 16 }, + /* 1730 */ { MAD_F(0x05120019) /* 0.316894625 */, 16 }, + /* 1731 */ { MAD_F(0x05130039) /* 0.317138884 */, 16 }, + /* 1732 */ { MAD_F(0x05140065) /* 0.317383189 */, 16 }, + /* 1733 */ { MAD_F(0x0515009e) /* 0.317627541 */, 16 }, + /* 1734 */ { MAD_F(0x051600e3) /* 0.317871941 */, 16 }, + /* 1735 */ { MAD_F(0x05170135) /* 0.318116387 */, 16 }, + /* 1736 */ { MAD_F(0x05180194) /* 0.318360880 */, 16 }, + /* 1737 */ { MAD_F(0x051901ff) /* 0.318605421 */, 16 }, + /* 1738 */ { MAD_F(0x051a0277) /* 0.318850008 */, 16 }, + /* 1739 */ { MAD_F(0x051b02fc) /* 0.319094642 */, 16 }, + /* 1740 */ { MAD_F(0x051c038d) /* 0.319339323 */, 16 }, + /* 1741 */ { MAD_F(0x051d042a) /* 0.319584051 */, 16 }, + /* 1742 */ { MAD_F(0x051e04d4) /* 0.319828826 */, 16 }, + /* 1743 */ { MAD_F(0x051f058b) /* 0.320073647 */, 16 }, + + /* 1744 */ { MAD_F(0x0520064f) /* 0.320318516 */, 16 }, + /* 1745 */ { MAD_F(0x0521071f) /* 0.320563431 */, 16 }, + /* 1746 */ { MAD_F(0x052207fb) /* 0.320808393 */, 16 }, + /* 1747 */ { MAD_F(0x052308e4) /* 0.321053402 */, 16 }, + /* 1748 */ { MAD_F(0x052409da) /* 0.321298457 */, 16 }, + /* 1749 */ { MAD_F(0x05250adc) /* 0.321543560 */, 16 }, + /* 1750 */ { MAD_F(0x05260bea) /* 0.321788709 */, 16 }, + /* 1751 */ { MAD_F(0x05270d06) /* 0.322033904 */, 16 }, + /* 1752 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 16 }, + /* 1753 */ { MAD_F(0x05290f62) /* 0.322524436 */, 16 }, + /* 1754 */ { MAD_F(0x052a10a3) /* 0.322769771 */, 16 }, + /* 1755 */ { MAD_F(0x052b11f0) /* 0.323015154 */, 16 }, + /* 1756 */ { MAD_F(0x052c134a) /* 0.323260583 */, 16 }, + /* 1757 */ { MAD_F(0x052d14b0) /* 0.323506058 */, 16 }, + /* 1758 */ { MAD_F(0x052e1623) /* 0.323751580 */, 16 }, + /* 1759 */ { MAD_F(0x052f17a2) /* 0.323997149 */, 16 }, + + /* 1760 */ { MAD_F(0x0530192e) /* 0.324242764 */, 16 }, + /* 1761 */ { MAD_F(0x05311ac6) /* 0.324488426 */, 16 }, + /* 1762 */ { MAD_F(0x05321c6b) /* 0.324734134 */, 16 }, + /* 1763 */ { MAD_F(0x05331e1c) /* 0.324979889 */, 16 }, + /* 1764 */ { MAD_F(0x05341fda) /* 0.325225690 */, 16 }, + /* 1765 */ { MAD_F(0x053521a4) /* 0.325471538 */, 16 }, + /* 1766 */ { MAD_F(0x0536237b) /* 0.325717432 */, 16 }, + /* 1767 */ { MAD_F(0x0537255e) /* 0.325963372 */, 16 }, + /* 1768 */ { MAD_F(0x0538274e) /* 0.326209359 */, 16 }, + /* 1769 */ { MAD_F(0x0539294a) /* 0.326455392 */, 16 }, + /* 1770 */ { MAD_F(0x053a2b52) /* 0.326701472 */, 16 }, + /* 1771 */ { MAD_F(0x053b2d67) /* 0.326947598 */, 16 }, + /* 1772 */ { MAD_F(0x053c2f89) /* 0.327193770 */, 16 }, + /* 1773 */ { MAD_F(0x053d31b6) /* 0.327439989 */, 16 }, + /* 1774 */ { MAD_F(0x053e33f1) /* 0.327686254 */, 16 }, + /* 1775 */ { MAD_F(0x053f3637) /* 0.327932565 */, 16 }, + + /* 1776 */ { MAD_F(0x0540388a) /* 0.328178922 */, 16 }, + /* 1777 */ { MAD_F(0x05413aea) /* 0.328425326 */, 16 }, + /* 1778 */ { MAD_F(0x05423d56) /* 0.328671776 */, 16 }, + /* 1779 */ { MAD_F(0x05433fce) /* 0.328918272 */, 16 }, + /* 1780 */ { MAD_F(0x05444253) /* 0.329164814 */, 16 }, + /* 1781 */ { MAD_F(0x054544e4) /* 0.329411403 */, 16 }, + /* 1782 */ { MAD_F(0x05464781) /* 0.329658038 */, 16 }, + /* 1783 */ { MAD_F(0x05474a2b) /* 0.329904718 */, 16 }, + /* 1784 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 16 }, + /* 1785 */ { MAD_F(0x05494fa4) /* 0.330398218 */, 16 }, + /* 1786 */ { MAD_F(0x054a5273) /* 0.330645037 */, 16 }, + /* 1787 */ { MAD_F(0x054b554e) /* 0.330891903 */, 16 }, + /* 1788 */ { MAD_F(0x054c5836) /* 0.331138814 */, 16 }, + /* 1789 */ { MAD_F(0x054d5b2a) /* 0.331385771 */, 16 }, + /* 1790 */ { MAD_F(0x054e5e2b) /* 0.331632774 */, 16 }, + /* 1791 */ { MAD_F(0x054f6138) /* 0.331879824 */, 16 }, + + /* 1792 */ { MAD_F(0x05506451) /* 0.332126919 */, 16 }, + /* 1793 */ { MAD_F(0x05516776) /* 0.332374060 */, 16 }, + /* 1794 */ { MAD_F(0x05526aa8) /* 0.332621247 */, 16 }, + /* 1795 */ { MAD_F(0x05536de6) /* 0.332868480 */, 16 }, + /* 1796 */ { MAD_F(0x05547131) /* 0.333115759 */, 16 }, + /* 1797 */ { MAD_F(0x05557487) /* 0.333363084 */, 16 }, + /* 1798 */ { MAD_F(0x055677ea) /* 0.333610455 */, 16 }, + /* 1799 */ { MAD_F(0x05577b5a) /* 0.333857872 */, 16 }, + /* 1800 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 16 }, + /* 1801 */ { MAD_F(0x0559825e) /* 0.334352843 */, 16 }, + /* 1802 */ { MAD_F(0x055a85f2) /* 0.334600397 */, 16 }, + /* 1803 */ { MAD_F(0x055b8992) /* 0.334847997 */, 16 }, + /* 1804 */ { MAD_F(0x055c8d3f) /* 0.335095642 */, 16 }, + /* 1805 */ { MAD_F(0x055d90f9) /* 0.335343334 */, 16 }, + /* 1806 */ { MAD_F(0x055e94be) /* 0.335591071 */, 16 }, + /* 1807 */ { MAD_F(0x055f9890) /* 0.335838854 */, 16 }, + + /* 1808 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 16 }, + /* 1809 */ { MAD_F(0x0561a058) /* 0.336334557 */, 16 }, + /* 1810 */ { MAD_F(0x0562a44f) /* 0.336582477 */, 16 }, + /* 1811 */ { MAD_F(0x0563a851) /* 0.336830443 */, 16 }, + /* 1812 */ { MAD_F(0x0564ac60) /* 0.337078454 */, 16 }, + /* 1813 */ { MAD_F(0x0565b07c) /* 0.337326511 */, 16 }, + /* 1814 */ { MAD_F(0x0566b4a3) /* 0.337574614 */, 16 }, + /* 1815 */ { MAD_F(0x0567b8d7) /* 0.337822762 */, 16 }, + /* 1816 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 16 }, + /* 1817 */ { MAD_F(0x0569c163) /* 0.338319195 */, 16 }, + /* 1818 */ { MAD_F(0x056ac5bc) /* 0.338567480 */, 16 }, + /* 1819 */ { MAD_F(0x056bca20) /* 0.338815811 */, 16 }, + /* 1820 */ { MAD_F(0x056cce91) /* 0.339064186 */, 16 }, + /* 1821 */ { MAD_F(0x056dd30e) /* 0.339312608 */, 16 }, + /* 1822 */ { MAD_F(0x056ed798) /* 0.339561075 */, 16 }, + /* 1823 */ { MAD_F(0x056fdc2d) /* 0.339809587 */, 16 }, + + /* 1824 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 16 }, + /* 1825 */ { MAD_F(0x0571e57d) /* 0.340306748 */, 16 }, + /* 1826 */ { MAD_F(0x0572ea37) /* 0.340555397 */, 16 }, + /* 1827 */ { MAD_F(0x0573eefd) /* 0.340804091 */, 16 }, + /* 1828 */ { MAD_F(0x0574f3d0) /* 0.341052830 */, 16 }, + /* 1829 */ { MAD_F(0x0575f8ae) /* 0.341301615 */, 16 }, + /* 1830 */ { MAD_F(0x0576fd99) /* 0.341550445 */, 16 }, + /* 1831 */ { MAD_F(0x05780290) /* 0.341799321 */, 16 }, + /* 1832 */ { MAD_F(0x05790793) /* 0.342048241 */, 16 }, + /* 1833 */ { MAD_F(0x057a0ca3) /* 0.342297207 */, 16 }, + /* 1834 */ { MAD_F(0x057b11be) /* 0.342546219 */, 16 }, + /* 1835 */ { MAD_F(0x057c16e6) /* 0.342795275 */, 16 }, + /* 1836 */ { MAD_F(0x057d1c1a) /* 0.343044377 */, 16 }, + /* 1837 */ { MAD_F(0x057e2159) /* 0.343293524 */, 16 }, + /* 1838 */ { MAD_F(0x057f26a6) /* 0.343542717 */, 16 }, + /* 1839 */ { MAD_F(0x05802bfe) /* 0.343791954 */, 16 }, + + /* 1840 */ { MAD_F(0x05813162) /* 0.344041237 */, 16 }, + /* 1841 */ { MAD_F(0x058236d2) /* 0.344290564 */, 16 }, + /* 1842 */ { MAD_F(0x05833c4f) /* 0.344539937 */, 16 }, + /* 1843 */ { MAD_F(0x058441d8) /* 0.344789356 */, 16 }, + /* 1844 */ { MAD_F(0x0585476c) /* 0.345038819 */, 16 }, + /* 1845 */ { MAD_F(0x05864d0d) /* 0.345288327 */, 16 }, + /* 1846 */ { MAD_F(0x058752ba) /* 0.345537880 */, 16 }, + /* 1847 */ { MAD_F(0x05885873) /* 0.345787479 */, 16 }, + /* 1848 */ { MAD_F(0x05895e39) /* 0.346037122 */, 16 }, + /* 1849 */ { MAD_F(0x058a640a) /* 0.346286811 */, 16 }, + /* 1850 */ { MAD_F(0x058b69e7) /* 0.346536545 */, 16 }, + /* 1851 */ { MAD_F(0x058c6fd1) /* 0.346786323 */, 16 }, + /* 1852 */ { MAD_F(0x058d75c6) /* 0.347036147 */, 16 }, + /* 1853 */ { MAD_F(0x058e7bc8) /* 0.347286015 */, 16 }, + /* 1854 */ { MAD_F(0x058f81d5) /* 0.347535929 */, 16 }, + /* 1855 */ { MAD_F(0x059087ef) /* 0.347785887 */, 16 }, + + /* 1856 */ { MAD_F(0x05918e15) /* 0.348035890 */, 16 }, + /* 1857 */ { MAD_F(0x05929447) /* 0.348285939 */, 16 }, + /* 1858 */ { MAD_F(0x05939a84) /* 0.348536032 */, 16 }, + /* 1859 */ { MAD_F(0x0594a0ce) /* 0.348786170 */, 16 }, + /* 1860 */ { MAD_F(0x0595a724) /* 0.349036353 */, 16 }, + /* 1861 */ { MAD_F(0x0596ad86) /* 0.349286580 */, 16 }, + /* 1862 */ { MAD_F(0x0597b3f4) /* 0.349536853 */, 16 }, + /* 1863 */ { MAD_F(0x0598ba6e) /* 0.349787170 */, 16 }, + /* 1864 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 16 }, + /* 1865 */ { MAD_F(0x059ac786) /* 0.350287939 */, 16 }, + /* 1866 */ { MAD_F(0x059bce25) /* 0.350538391 */, 16 }, + /* 1867 */ { MAD_F(0x059cd4cf) /* 0.350788887 */, 16 }, + /* 1868 */ { MAD_F(0x059ddb85) /* 0.351039428 */, 16 }, + /* 1869 */ { MAD_F(0x059ee247) /* 0.351290014 */, 16 }, + /* 1870 */ { MAD_F(0x059fe915) /* 0.351540645 */, 16 }, + /* 1871 */ { MAD_F(0x05a0efef) /* 0.351791320 */, 16 }, + + /* 1872 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 16 }, + /* 1873 */ { MAD_F(0x05a2fdc7) /* 0.352292804 */, 16 }, + /* 1874 */ { MAD_F(0x05a404c5) /* 0.352543613 */, 16 }, + /* 1875 */ { MAD_F(0x05a50bcf) /* 0.352794467 */, 16 }, + /* 1876 */ { MAD_F(0x05a612e5) /* 0.353045365 */, 16 }, + /* 1877 */ { MAD_F(0x05a71a07) /* 0.353296308 */, 16 }, + /* 1878 */ { MAD_F(0x05a82135) /* 0.353547296 */, 16 }, + /* 1879 */ { MAD_F(0x05a9286f) /* 0.353798328 */, 16 }, + /* 1880 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 16 }, + /* 1881 */ { MAD_F(0x05ab3707) /* 0.354300526 */, 16 }, + /* 1882 */ { MAD_F(0x05ac3e65) /* 0.354551691 */, 16 }, + /* 1883 */ { MAD_F(0x05ad45ce) /* 0.354802901 */, 16 }, + /* 1884 */ { MAD_F(0x05ae4d44) /* 0.355054156 */, 16 }, + /* 1885 */ { MAD_F(0x05af54c6) /* 0.355305455 */, 16 }, + /* 1886 */ { MAD_F(0x05b05c53) /* 0.355556799 */, 16 }, + /* 1887 */ { MAD_F(0x05b163ed) /* 0.355808187 */, 16 }, + + /* 1888 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 16 }, + /* 1889 */ { MAD_F(0x05b37343) /* 0.356311096 */, 16 }, + /* 1890 */ { MAD_F(0x05b47b00) /* 0.356562617 */, 16 }, + /* 1891 */ { MAD_F(0x05b582c9) /* 0.356814182 */, 16 }, + /* 1892 */ { MAD_F(0x05b68a9e) /* 0.357065792 */, 16 }, + /* 1893 */ { MAD_F(0x05b7927f) /* 0.357317446 */, 16 }, + /* 1894 */ { MAD_F(0x05b89a6c) /* 0.357569145 */, 16 }, + /* 1895 */ { MAD_F(0x05b9a265) /* 0.357820887 */, 16 }, + /* 1896 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 16 }, + /* 1897 */ { MAD_F(0x05bbb27a) /* 0.358324506 */, 16 }, + /* 1898 */ { MAD_F(0x05bcba96) /* 0.358576381 */, 16 }, + /* 1899 */ { MAD_F(0x05bdc2be) /* 0.358828301 */, 16 }, + /* 1900 */ { MAD_F(0x05becaf2) /* 0.359080265 */, 16 }, + /* 1901 */ { MAD_F(0x05bfd332) /* 0.359332273 */, 16 }, + /* 1902 */ { MAD_F(0x05c0db7e) /* 0.359584326 */, 16 }, + /* 1903 */ { MAD_F(0x05c1e3d6) /* 0.359836423 */, 16 }, + + /* 1904 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 16 }, + /* 1905 */ { MAD_F(0x05c3f4a9) /* 0.360340748 */, 16 }, + /* 1906 */ { MAD_F(0x05c4fd24) /* 0.360592977 */, 16 }, + /* 1907 */ { MAD_F(0x05c605ab) /* 0.360845251 */, 16 }, + /* 1908 */ { MAD_F(0x05c70e3e) /* 0.361097568 */, 16 }, + /* 1909 */ { MAD_F(0x05c816dd) /* 0.361349929 */, 16 }, + /* 1910 */ { MAD_F(0x05c91f87) /* 0.361602335 */, 16 }, + /* 1911 */ { MAD_F(0x05ca283e) /* 0.361854784 */, 16 }, + /* 1912 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 16 }, + /* 1913 */ { MAD_F(0x05cc39ce) /* 0.362359815 */, 16 }, + /* 1914 */ { MAD_F(0x05cd42a8) /* 0.362612397 */, 16 }, + /* 1915 */ { MAD_F(0x05ce4b8d) /* 0.362865022 */, 16 }, + /* 1916 */ { MAD_F(0x05cf547f) /* 0.363117692 */, 16 }, + /* 1917 */ { MAD_F(0x05d05d7c) /* 0.363370405 */, 16 }, + /* 1918 */ { MAD_F(0x05d16685) /* 0.363623163 */, 16 }, + /* 1919 */ { MAD_F(0x05d26f9a) /* 0.363875964 */, 16 }, + + /* 1920 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 16 }, + /* 1921 */ { MAD_F(0x05d481e7) /* 0.364381698 */, 16 }, + /* 1922 */ { MAD_F(0x05d58b1f) /* 0.364634632 */, 16 }, + /* 1923 */ { MAD_F(0x05d69463) /* 0.364887608 */, 16 }, + /* 1924 */ { MAD_F(0x05d79db3) /* 0.365140629 */, 16 }, + /* 1925 */ { MAD_F(0x05d8a70f) /* 0.365393694 */, 16 }, + /* 1926 */ { MAD_F(0x05d9b076) /* 0.365646802 */, 16 }, + /* 1927 */ { MAD_F(0x05dab9e9) /* 0.365899955 */, 16 }, + /* 1928 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 16 }, + /* 1929 */ { MAD_F(0x05dcccf2) /* 0.366406390 */, 16 }, + /* 1930 */ { MAD_F(0x05ddd689) /* 0.366659674 */, 16 }, + /* 1931 */ { MAD_F(0x05dee02b) /* 0.366913001 */, 16 }, + /* 1932 */ { MAD_F(0x05dfe9d8) /* 0.367166372 */, 16 }, + /* 1933 */ { MAD_F(0x05e0f392) /* 0.367419787 */, 16 }, + /* 1934 */ { MAD_F(0x05e1fd57) /* 0.367673246 */, 16 }, + /* 1935 */ { MAD_F(0x05e30728) /* 0.367926748 */, 16 }, + + /* 1936 */ { MAD_F(0x05e41105) /* 0.368180294 */, 16 }, + /* 1937 */ { MAD_F(0x05e51aed) /* 0.368433883 */, 16 }, + /* 1938 */ { MAD_F(0x05e624e1) /* 0.368687517 */, 16 }, + /* 1939 */ { MAD_F(0x05e72ee1) /* 0.368941193 */, 16 }, + /* 1940 */ { MAD_F(0x05e838ed) /* 0.369194914 */, 16 }, + /* 1941 */ { MAD_F(0x05e94304) /* 0.369448678 */, 16 }, + /* 1942 */ { MAD_F(0x05ea4d27) /* 0.369702485 */, 16 }, + /* 1943 */ { MAD_F(0x05eb5756) /* 0.369956336 */, 16 }, + /* 1944 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 16 }, + /* 1945 */ { MAD_F(0x05ed6bd6) /* 0.370464169 */, 16 }, + /* 1946 */ { MAD_F(0x05ee7628) /* 0.370718151 */, 16 }, + /* 1947 */ { MAD_F(0x05ef8085) /* 0.370972177 */, 16 }, + /* 1948 */ { MAD_F(0x05f08aee) /* 0.371226245 */, 16 }, + /* 1949 */ { MAD_F(0x05f19563) /* 0.371480358 */, 16 }, + /* 1950 */ { MAD_F(0x05f29fe3) /* 0.371734513 */, 16 }, + /* 1951 */ { MAD_F(0x05f3aa6f) /* 0.371988712 */, 16 }, + + /* 1952 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 16 }, + /* 1953 */ { MAD_F(0x05f5bfab) /* 0.372497241 */, 16 }, + /* 1954 */ { MAD_F(0x05f6ca5a) /* 0.372751570 */, 16 }, + /* 1955 */ { MAD_F(0x05f7d514) /* 0.373005943 */, 16 }, + /* 1956 */ { MAD_F(0x05f8dfdb) /* 0.373260359 */, 16 }, + /* 1957 */ { MAD_F(0x05f9eaad) /* 0.373514819 */, 16 }, + /* 1958 */ { MAD_F(0x05faf58a) /* 0.373769322 */, 16 }, + /* 1959 */ { MAD_F(0x05fc0073) /* 0.374023868 */, 16 }, + /* 1960 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 16 }, + /* 1961 */ { MAD_F(0x05fe1669) /* 0.374533091 */, 16 }, + /* 1962 */ { MAD_F(0x05ff2175) /* 0.374787767 */, 16 }, + /* 1963 */ { MAD_F(0x06002c8d) /* 0.375042486 */, 16 }, + /* 1964 */ { MAD_F(0x060137b0) /* 0.375297249 */, 16 }, + /* 1965 */ { MAD_F(0x060242df) /* 0.375552055 */, 16 }, + /* 1966 */ { MAD_F(0x06034e19) /* 0.375806904 */, 16 }, + /* 1967 */ { MAD_F(0x0604595f) /* 0.376061796 */, 16 }, + + /* 1968 */ { MAD_F(0x060564b1) /* 0.376316732 */, 16 }, + /* 1969 */ { MAD_F(0x0606700f) /* 0.376571710 */, 16 }, + /* 1970 */ { MAD_F(0x06077b77) /* 0.376826732 */, 16 }, + /* 1971 */ { MAD_F(0x060886ec) /* 0.377081797 */, 16 }, + /* 1972 */ { MAD_F(0x0609926c) /* 0.377336905 */, 16 }, + /* 1973 */ { MAD_F(0x060a9df8) /* 0.377592057 */, 16 }, + /* 1974 */ { MAD_F(0x060ba98f) /* 0.377847251 */, 16 }, + /* 1975 */ { MAD_F(0x060cb532) /* 0.378102489 */, 16 }, + /* 1976 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 16 }, + /* 1977 */ { MAD_F(0x060ecc9a) /* 0.378613093 */, 16 }, + /* 1978 */ { MAD_F(0x060fd860) /* 0.378868460 */, 16 }, + /* 1979 */ { MAD_F(0x0610e431) /* 0.379123870 */, 16 }, + /* 1980 */ { MAD_F(0x0611f00d) /* 0.379379322 */, 16 }, + /* 1981 */ { MAD_F(0x0612fbf5) /* 0.379634818 */, 16 }, + /* 1982 */ { MAD_F(0x061407e9) /* 0.379890357 */, 16 }, + /* 1983 */ { MAD_F(0x061513e8) /* 0.380145939 */, 16 }, + + /* 1984 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 16 }, + /* 1985 */ { MAD_F(0x06172c09) /* 0.380657231 */, 16 }, + /* 1986 */ { MAD_F(0x0618382b) /* 0.380912942 */, 16 }, + /* 1987 */ { MAD_F(0x06194458) /* 0.381168695 */, 16 }, + /* 1988 */ { MAD_F(0x061a5091) /* 0.381424492 */, 16 }, + /* 1989 */ { MAD_F(0x061b5cd5) /* 0.381680331 */, 16 }, + /* 1990 */ { MAD_F(0x061c6925) /* 0.381936213 */, 16 }, + /* 1991 */ { MAD_F(0x061d7581) /* 0.382192138 */, 16 }, + /* 1992 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 16 }, + /* 1993 */ { MAD_F(0x061f8e5a) /* 0.382704117 */, 16 }, + /* 1994 */ { MAD_F(0x06209ad8) /* 0.382960171 */, 16 }, + /* 1995 */ { MAD_F(0x0621a761) /* 0.383216267 */, 16 }, + /* 1996 */ { MAD_F(0x0622b3f6) /* 0.383472406 */, 16 }, + /* 1997 */ { MAD_F(0x0623c096) /* 0.383728588 */, 16 }, + /* 1998 */ { MAD_F(0x0624cd42) /* 0.383984813 */, 16 }, + /* 1999 */ { MAD_F(0x0625d9f9) /* 0.384241080 */, 16 }, + + /* 2000 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 16 }, + /* 2001 */ { MAD_F(0x0627f38a) /* 0.384753744 */, 16 }, + /* 2002 */ { MAD_F(0x06290064) /* 0.385010139 */, 16 }, + /* 2003 */ { MAD_F(0x062a0d49) /* 0.385266578 */, 16 }, + /* 2004 */ { MAD_F(0x062b1a3a) /* 0.385523059 */, 16 }, + /* 2005 */ { MAD_F(0x062c2736) /* 0.385779582 */, 16 }, + /* 2006 */ { MAD_F(0x062d343d) /* 0.386036149 */, 16 }, + /* 2007 */ { MAD_F(0x062e4150) /* 0.386292758 */, 16 }, + /* 2008 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 16 }, + /* 2009 */ { MAD_F(0x06305b99) /* 0.386806104 */, 16 }, + /* 2010 */ { MAD_F(0x063168ce) /* 0.387062840 */, 16 }, + /* 2011 */ { MAD_F(0x0632760f) /* 0.387319620 */, 16 }, + /* 2012 */ { MAD_F(0x0633835b) /* 0.387576442 */, 16 }, + /* 2013 */ { MAD_F(0x063490b2) /* 0.387833306 */, 16 }, + /* 2014 */ { MAD_F(0x06359e15) /* 0.388090213 */, 16 }, + /* 2015 */ { MAD_F(0x0636ab83) /* 0.388347163 */, 16 }, + + /* 2016 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 16 }, + /* 2017 */ { MAD_F(0x0638c682) /* 0.388861190 */, 16 }, + /* 2018 */ { MAD_F(0x0639d413) /* 0.389118267 */, 16 }, + /* 2019 */ { MAD_F(0x063ae1af) /* 0.389375386 */, 16 }, + /* 2020 */ { MAD_F(0x063bef56) /* 0.389632548 */, 16 }, + /* 2021 */ { MAD_F(0x063cfd09) /* 0.389889752 */, 16 }, + /* 2022 */ { MAD_F(0x063e0ac7) /* 0.390146999 */, 16 }, + /* 2023 */ { MAD_F(0x063f1891) /* 0.390404289 */, 16 }, + /* 2024 */ { MAD_F(0x06402666) /* 0.390661620 */, 16 }, + /* 2025 */ { MAD_F(0x06413446) /* 0.390918994 */, 16 }, + /* 2026 */ { MAD_F(0x06424232) /* 0.391176411 */, 16 }, + /* 2027 */ { MAD_F(0x06435029) /* 0.391433869 */, 16 }, + /* 2028 */ { MAD_F(0x06445e2b) /* 0.391691371 */, 16 }, + /* 2029 */ { MAD_F(0x06456c39) /* 0.391948914 */, 16 }, + /* 2030 */ { MAD_F(0x06467a52) /* 0.392206500 */, 16 }, + /* 2031 */ { MAD_F(0x06478877) /* 0.392464128 */, 16 }, + + /* 2032 */ { MAD_F(0x064896a7) /* 0.392721798 */, 16 }, + /* 2033 */ { MAD_F(0x0649a4e2) /* 0.392979511 */, 16 }, + /* 2034 */ { MAD_F(0x064ab328) /* 0.393237266 */, 16 }, + /* 2035 */ { MAD_F(0x064bc17a) /* 0.393495063 */, 16 }, + /* 2036 */ { MAD_F(0x064ccfd8) /* 0.393752902 */, 16 }, + /* 2037 */ { MAD_F(0x064dde40) /* 0.394010784 */, 16 }, + /* 2038 */ { MAD_F(0x064eecb4) /* 0.394268707 */, 16 }, + /* 2039 */ { MAD_F(0x064ffb33) /* 0.394526673 */, 16 }, + /* 2040 */ { MAD_F(0x065109be) /* 0.394784681 */, 16 }, + /* 2041 */ { MAD_F(0x06521854) /* 0.395042732 */, 16 }, + /* 2042 */ { MAD_F(0x065326f5) /* 0.395300824 */, 16 }, + /* 2043 */ { MAD_F(0x065435a1) /* 0.395558959 */, 16 }, + /* 2044 */ { MAD_F(0x06554459) /* 0.395817135 */, 16 }, + /* 2045 */ { MAD_F(0x0656531c) /* 0.396075354 */, 16 }, + /* 2046 */ { MAD_F(0x065761ea) /* 0.396333615 */, 16 }, + /* 2047 */ { MAD_F(0x065870c4) /* 0.396591918 */, 16 }, + + /* 2048 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 16 }, + /* 2049 */ { MAD_F(0x065a8e99) /* 0.397108650 */, 16 }, + /* 2050 */ { MAD_F(0x065b9d95) /* 0.397367079 */, 16 }, + /* 2051 */ { MAD_F(0x065cac9c) /* 0.397625550 */, 16 }, + /* 2052 */ { MAD_F(0x065dbbae) /* 0.397884063 */, 16 }, + /* 2053 */ { MAD_F(0x065ecacb) /* 0.398142619 */, 16 }, + /* 2054 */ { MAD_F(0x065fd9f4) /* 0.398401216 */, 16 }, + /* 2055 */ { MAD_F(0x0660e928) /* 0.398659855 */, 16 }, + /* 2056 */ { MAD_F(0x0661f867) /* 0.398918536 */, 16 }, + /* 2057 */ { MAD_F(0x066307b1) /* 0.399177259 */, 16 }, + /* 2058 */ { MAD_F(0x06641707) /* 0.399436024 */, 16 }, + /* 2059 */ { MAD_F(0x06652668) /* 0.399694831 */, 16 }, + /* 2060 */ { MAD_F(0x066635d4) /* 0.399953679 */, 16 }, + /* 2061 */ { MAD_F(0x0667454c) /* 0.400212570 */, 16 }, + /* 2062 */ { MAD_F(0x066854ce) /* 0.400471503 */, 16 }, + /* 2063 */ { MAD_F(0x0669645c) /* 0.400730477 */, 16 }, + + /* 2064 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 16 }, + /* 2065 */ { MAD_F(0x066b839a) /* 0.401248551 */, 16 }, + /* 2066 */ { MAD_F(0x066c9349) /* 0.401507651 */, 16 }, + /* 2067 */ { MAD_F(0x066da304) /* 0.401766793 */, 16 }, + /* 2068 */ { MAD_F(0x066eb2ca) /* 0.402025976 */, 16 }, + /* 2069 */ { MAD_F(0x066fc29b) /* 0.402285202 */, 16 }, + /* 2070 */ { MAD_F(0x0670d278) /* 0.402544469 */, 16 }, + /* 2071 */ { MAD_F(0x0671e25f) /* 0.402803777 */, 16 }, + /* 2072 */ { MAD_F(0x0672f252) /* 0.403063128 */, 16 }, + /* 2073 */ { MAD_F(0x06740250) /* 0.403322520 */, 16 }, + /* 2074 */ { MAD_F(0x0675125a) /* 0.403581954 */, 16 }, + /* 2075 */ { MAD_F(0x0676226e) /* 0.403841430 */, 16 }, + /* 2076 */ { MAD_F(0x0677328e) /* 0.404100947 */, 16 }, + /* 2077 */ { MAD_F(0x067842b9) /* 0.404360506 */, 16 }, + /* 2078 */ { MAD_F(0x067952ef) /* 0.404620107 */, 16 }, + /* 2079 */ { MAD_F(0x067a6330) /* 0.404879749 */, 16 }, + + /* 2080 */ { MAD_F(0x067b737c) /* 0.405139433 */, 16 }, + /* 2081 */ { MAD_F(0x067c83d4) /* 0.405399159 */, 16 }, + /* 2082 */ { MAD_F(0x067d9436) /* 0.405658926 */, 16 }, + /* 2083 */ { MAD_F(0x067ea4a4) /* 0.405918735 */, 16 }, + /* 2084 */ { MAD_F(0x067fb51d) /* 0.406178585 */, 16 }, + /* 2085 */ { MAD_F(0x0680c5a2) /* 0.406438477 */, 16 }, + /* 2086 */ { MAD_F(0x0681d631) /* 0.406698410 */, 16 }, + /* 2087 */ { MAD_F(0x0682e6cb) /* 0.406958385 */, 16 }, + /* 2088 */ { MAD_F(0x0683f771) /* 0.407218402 */, 16 }, + /* 2089 */ { MAD_F(0x06850822) /* 0.407478460 */, 16 }, + /* 2090 */ { MAD_F(0x068618de) /* 0.407738559 */, 16 }, + /* 2091 */ { MAD_F(0x068729a5) /* 0.407998700 */, 16 }, + /* 2092 */ { MAD_F(0x06883a77) /* 0.408258883 */, 16 }, + /* 2093 */ { MAD_F(0x06894b55) /* 0.408519107 */, 16 }, + /* 2094 */ { MAD_F(0x068a5c3d) /* 0.408779372 */, 16 }, + /* 2095 */ { MAD_F(0x068b6d31) /* 0.409039679 */, 16 }, + + /* 2096 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 16 }, + /* 2097 */ { MAD_F(0x068d8f39) /* 0.409560417 */, 16 }, + /* 2098 */ { MAD_F(0x068ea04e) /* 0.409820848 */, 16 }, + /* 2099 */ { MAD_F(0x068fb16e) /* 0.410081321 */, 16 }, + /* 2100 */ { MAD_F(0x0690c299) /* 0.410341834 */, 16 }, + /* 2101 */ { MAD_F(0x0691d3cf) /* 0.410602390 */, 16 }, + /* 2102 */ { MAD_F(0x0692e511) /* 0.410862986 */, 16 }, + /* 2103 */ { MAD_F(0x0693f65d) /* 0.411123624 */, 16 }, + /* 2104 */ { MAD_F(0x069507b5) /* 0.411384303 */, 16 }, + /* 2105 */ { MAD_F(0x06961917) /* 0.411645024 */, 16 }, + /* 2106 */ { MAD_F(0x06972a85) /* 0.411905785 */, 16 }, + /* 2107 */ { MAD_F(0x06983bfe) /* 0.412166588 */, 16 }, + /* 2108 */ { MAD_F(0x06994d82) /* 0.412427433 */, 16 }, + /* 2109 */ { MAD_F(0x069a5f11) /* 0.412688318 */, 16 }, + /* 2110 */ { MAD_F(0x069b70ab) /* 0.412949245 */, 16 }, + /* 2111 */ { MAD_F(0x069c8250) /* 0.413210213 */, 16 }, + + /* 2112 */ { MAD_F(0x069d9400) /* 0.413471222 */, 16 }, + /* 2113 */ { MAD_F(0x069ea5bb) /* 0.413732273 */, 16 }, + /* 2114 */ { MAD_F(0x069fb781) /* 0.413993364 */, 16 }, + /* 2115 */ { MAD_F(0x06a0c953) /* 0.414254497 */, 16 }, + /* 2116 */ { MAD_F(0x06a1db2f) /* 0.414515671 */, 16 }, + /* 2117 */ { MAD_F(0x06a2ed16) /* 0.414776886 */, 16 }, + /* 2118 */ { MAD_F(0x06a3ff09) /* 0.415038142 */, 16 }, + /* 2119 */ { MAD_F(0x06a51106) /* 0.415299440 */, 16 }, + /* 2120 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 16 }, + /* 2121 */ { MAD_F(0x06a73522) /* 0.415822157 */, 16 }, + /* 2122 */ { MAD_F(0x06a84741) /* 0.416083578 */, 16 }, + /* 2123 */ { MAD_F(0x06a9596a) /* 0.416345040 */, 16 }, + /* 2124 */ { MAD_F(0x06aa6b9f) /* 0.416606542 */, 16 }, + /* 2125 */ { MAD_F(0x06ab7ddf) /* 0.416868086 */, 16 }, + /* 2126 */ { MAD_F(0x06ac9029) /* 0.417129671 */, 16 }, + /* 2127 */ { MAD_F(0x06ada27f) /* 0.417391297 */, 16 }, + + /* 2128 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 16 }, + /* 2129 */ { MAD_F(0x06afc74b) /* 0.417914672 */, 16 }, + /* 2130 */ { MAD_F(0x06b0d9c2) /* 0.418176420 */, 16 }, + /* 2131 */ { MAD_F(0x06b1ec43) /* 0.418438210 */, 16 }, + /* 2132 */ { MAD_F(0x06b2fed0) /* 0.418700041 */, 16 }, + /* 2133 */ { MAD_F(0x06b41168) /* 0.418961912 */, 16 }, + /* 2134 */ { MAD_F(0x06b5240a) /* 0.419223825 */, 16 }, + /* 2135 */ { MAD_F(0x06b636b8) /* 0.419485778 */, 16 }, + /* 2136 */ { MAD_F(0x06b74971) /* 0.419747773 */, 16 }, + /* 2137 */ { MAD_F(0x06b85c34) /* 0.420009808 */, 16 }, + /* 2138 */ { MAD_F(0x06b96f03) /* 0.420271884 */, 16 }, + /* 2139 */ { MAD_F(0x06ba81dc) /* 0.420534001 */, 16 }, + /* 2140 */ { MAD_F(0x06bb94c1) /* 0.420796159 */, 16 }, + /* 2141 */ { MAD_F(0x06bca7b0) /* 0.421058358 */, 16 }, + /* 2142 */ { MAD_F(0x06bdbaaa) /* 0.421320597 */, 16 }, + /* 2143 */ { MAD_F(0x06becdb0) /* 0.421582878 */, 16 }, + + /* 2144 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 16 }, + /* 2145 */ { MAD_F(0x06c0f3db) /* 0.422107561 */, 16 }, + /* 2146 */ { MAD_F(0x06c20702) /* 0.422369964 */, 16 }, + /* 2147 */ { MAD_F(0x06c31a33) /* 0.422632407 */, 16 }, + /* 2148 */ { MAD_F(0x06c42d6f) /* 0.422894891 */, 16 }, + /* 2149 */ { MAD_F(0x06c540b6) /* 0.423157416 */, 16 }, + /* 2150 */ { MAD_F(0x06c65408) /* 0.423419982 */, 16 }, + /* 2151 */ { MAD_F(0x06c76765) /* 0.423682588 */, 16 }, + /* 2152 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 16 }, + /* 2153 */ { MAD_F(0x06c98e3f) /* 0.424207923 */, 16 }, + /* 2154 */ { MAD_F(0x06caa1bd) /* 0.424470652 */, 16 }, + /* 2155 */ { MAD_F(0x06cbb545) /* 0.424733421 */, 16 }, + /* 2156 */ { MAD_F(0x06ccc8d9) /* 0.424996230 */, 16 }, + /* 2157 */ { MAD_F(0x06cddc77) /* 0.425259081 */, 16 }, + /* 2158 */ { MAD_F(0x06cef020) /* 0.425521972 */, 16 }, + /* 2159 */ { MAD_F(0x06d003d4) /* 0.425784903 */, 16 }, + + /* 2160 */ { MAD_F(0x06d11794) /* 0.426047876 */, 16 }, + /* 2161 */ { MAD_F(0x06d22b5e) /* 0.426310889 */, 16 }, + /* 2162 */ { MAD_F(0x06d33f32) /* 0.426573942 */, 16 }, + /* 2163 */ { MAD_F(0x06d45312) /* 0.426837036 */, 16 }, + /* 2164 */ { MAD_F(0x06d566fd) /* 0.427100170 */, 16 }, + /* 2165 */ { MAD_F(0x06d67af2) /* 0.427363345 */, 16 }, + /* 2166 */ { MAD_F(0x06d78ef3) /* 0.427626561 */, 16 }, + /* 2167 */ { MAD_F(0x06d8a2fe) /* 0.427889817 */, 16 }, + /* 2168 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 16 }, + /* 2169 */ { MAD_F(0x06dacb35) /* 0.428416451 */, 16 }, + /* 2170 */ { MAD_F(0x06dbdf61) /* 0.428679828 */, 16 }, + /* 2171 */ { MAD_F(0x06dcf398) /* 0.428943246 */, 16 }, + /* 2172 */ { MAD_F(0x06de07d9) /* 0.429206704 */, 16 }, + /* 2173 */ { MAD_F(0x06df1c26) /* 0.429470203 */, 16 }, + /* 2174 */ { MAD_F(0x06e0307d) /* 0.429733743 */, 16 }, + /* 2175 */ { MAD_F(0x06e144df) /* 0.429997322 */, 16 }, + + /* 2176 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 16 }, + /* 2177 */ { MAD_F(0x06e36dc4) /* 0.430524603 */, 16 }, + /* 2178 */ { MAD_F(0x06e48246) /* 0.430788304 */, 16 }, + /* 2179 */ { MAD_F(0x06e596d4) /* 0.431052045 */, 16 }, + /* 2180 */ { MAD_F(0x06e6ab6c) /* 0.431315826 */, 16 }, + /* 2181 */ { MAD_F(0x06e7c00f) /* 0.431579648 */, 16 }, + /* 2182 */ { MAD_F(0x06e8d4bd) /* 0.431843511 */, 16 }, + /* 2183 */ { MAD_F(0x06e9e976) /* 0.432107413 */, 16 }, + /* 2184 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 16 }, + /* 2185 */ { MAD_F(0x06ec1308) /* 0.432635339 */, 16 }, + /* 2186 */ { MAD_F(0x06ed27e2) /* 0.432899362 */, 16 }, + /* 2187 */ { MAD_F(0x06ee3cc6) /* 0.433163426 */, 16 }, + /* 2188 */ { MAD_F(0x06ef51b4) /* 0.433427530 */, 16 }, + /* 2189 */ { MAD_F(0x06f066ae) /* 0.433691674 */, 16 }, + /* 2190 */ { MAD_F(0x06f17bb3) /* 0.433955859 */, 16 }, + /* 2191 */ { MAD_F(0x06f290c2) /* 0.434220083 */, 16 }, + + /* 2192 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 16 }, + /* 2193 */ { MAD_F(0x06f4bb01) /* 0.434748653 */, 16 }, + /* 2194 */ { MAD_F(0x06f5d030) /* 0.435012998 */, 16 }, + /* 2195 */ { MAD_F(0x06f6e56b) /* 0.435277383 */, 16 }, + /* 2196 */ { MAD_F(0x06f7fab0) /* 0.435541809 */, 16 }, + /* 2197 */ { MAD_F(0x06f91000) /* 0.435806274 */, 16 }, + /* 2198 */ { MAD_F(0x06fa255a) /* 0.436070780 */, 16 }, + /* 2199 */ { MAD_F(0x06fb3ac0) /* 0.436335326 */, 16 }, + /* 2200 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 16 }, + /* 2201 */ { MAD_F(0x06fd65ab) /* 0.436864538 */, 16 }, + /* 2202 */ { MAD_F(0x06fe7b31) /* 0.437129204 */, 16 }, + /* 2203 */ { MAD_F(0x06ff90c2) /* 0.437393910 */, 16 }, + /* 2204 */ { MAD_F(0x0700a65d) /* 0.437658657 */, 16 }, + /* 2205 */ { MAD_F(0x0701bc03) /* 0.437923443 */, 16 }, + /* 2206 */ { MAD_F(0x0702d1b4) /* 0.438188269 */, 16 }, + /* 2207 */ { MAD_F(0x0703e76f) /* 0.438453136 */, 16 }, + + /* 2208 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 16 }, + /* 2209 */ { MAD_F(0x07061306) /* 0.438982988 */, 16 }, + /* 2210 */ { MAD_F(0x070728e2) /* 0.439247975 */, 16 }, + /* 2211 */ { MAD_F(0x07083ec9) /* 0.439513001 */, 16 }, + /* 2212 */ { MAD_F(0x070954ba) /* 0.439778067 */, 16 }, + /* 2213 */ { MAD_F(0x070a6ab6) /* 0.440043173 */, 16 }, + /* 2214 */ { MAD_F(0x070b80bc) /* 0.440308320 */, 16 }, + /* 2215 */ { MAD_F(0x070c96ce) /* 0.440573506 */, 16 }, + /* 2216 */ { MAD_F(0x070dacea) /* 0.440838732 */, 16 }, + /* 2217 */ { MAD_F(0x070ec310) /* 0.441103997 */, 16 }, + /* 2218 */ { MAD_F(0x070fd942) /* 0.441369303 */, 16 }, + /* 2219 */ { MAD_F(0x0710ef7e) /* 0.441634649 */, 16 }, + /* 2220 */ { MAD_F(0x071205c5) /* 0.441900034 */, 16 }, + /* 2221 */ { MAD_F(0x07131c17) /* 0.442165460 */, 16 }, + /* 2222 */ { MAD_F(0x07143273) /* 0.442430925 */, 16 }, + /* 2223 */ { MAD_F(0x071548da) /* 0.442696430 */, 16 }, + + /* 2224 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 16 }, + /* 2225 */ { MAD_F(0x071775c8) /* 0.443227559 */, 16 }, + /* 2226 */ { MAD_F(0x07188c4f) /* 0.443493184 */, 16 }, + /* 2227 */ { MAD_F(0x0719a2e0) /* 0.443758848 */, 16 }, + /* 2228 */ { MAD_F(0x071ab97d) /* 0.444024552 */, 16 }, + /* 2229 */ { MAD_F(0x071bd024) /* 0.444290296 */, 16 }, + /* 2230 */ { MAD_F(0x071ce6d6) /* 0.444556079 */, 16 }, + /* 2231 */ { MAD_F(0x071dfd92) /* 0.444821902 */, 16 }, + /* 2232 */ { MAD_F(0x071f1459) /* 0.445087765 */, 16 }, + /* 2233 */ { MAD_F(0x07202b2b) /* 0.445353668 */, 16 }, + /* 2234 */ { MAD_F(0x07214207) /* 0.445619610 */, 16 }, + /* 2235 */ { MAD_F(0x072258ee) /* 0.445885592 */, 16 }, + /* 2236 */ { MAD_F(0x07236fe0) /* 0.446151614 */, 16 }, + /* 2237 */ { MAD_F(0x072486dc) /* 0.446417675 */, 16 }, + /* 2238 */ { MAD_F(0x07259de3) /* 0.446683776 */, 16 }, + /* 2239 */ { MAD_F(0x0726b4f4) /* 0.446949917 */, 16 }, + + /* 2240 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 16 }, + /* 2241 */ { MAD_F(0x0728e338) /* 0.447482317 */, 16 }, + /* 2242 */ { MAD_F(0x0729fa69) /* 0.447748576 */, 16 }, + /* 2243 */ { MAD_F(0x072b11a5) /* 0.448014875 */, 16 }, + /* 2244 */ { MAD_F(0x072c28ec) /* 0.448281214 */, 16 }, + /* 2245 */ { MAD_F(0x072d403d) /* 0.448547592 */, 16 }, + /* 2246 */ { MAD_F(0x072e5799) /* 0.448814010 */, 16 }, + /* 2247 */ { MAD_F(0x072f6f00) /* 0.449080467 */, 16 }, + /* 2248 */ { MAD_F(0x07308671) /* 0.449346964 */, 16 }, + /* 2249 */ { MAD_F(0x07319ded) /* 0.449613501 */, 16 }, + /* 2250 */ { MAD_F(0x0732b573) /* 0.449880076 */, 16 }, + /* 2251 */ { MAD_F(0x0733cd04) /* 0.450146692 */, 16 }, + /* 2252 */ { MAD_F(0x0734e4a0) /* 0.450413347 */, 16 }, + /* 2253 */ { MAD_F(0x0735fc46) /* 0.450680041 */, 16 }, + /* 2254 */ { MAD_F(0x073713f7) /* 0.450946775 */, 16 }, + /* 2255 */ { MAD_F(0x07382bb2) /* 0.451213548 */, 16 }, + + /* 2256 */ { MAD_F(0x07394378) /* 0.451480360 */, 16 }, + /* 2257 */ { MAD_F(0x073a5b49) /* 0.451747213 */, 16 }, + /* 2258 */ { MAD_F(0x073b7324) /* 0.452014104 */, 16 }, + /* 2259 */ { MAD_F(0x073c8b0a) /* 0.452281035 */, 16 }, + /* 2260 */ { MAD_F(0x073da2fa) /* 0.452548005 */, 16 }, + /* 2261 */ { MAD_F(0x073ebaf5) /* 0.452815015 */, 16 }, + /* 2262 */ { MAD_F(0x073fd2fa) /* 0.453082064 */, 16 }, + /* 2263 */ { MAD_F(0x0740eb0a) /* 0.453349152 */, 16 }, + /* 2264 */ { MAD_F(0x07420325) /* 0.453616280 */, 16 }, + /* 2265 */ { MAD_F(0x07431b4a) /* 0.453883447 */, 16 }, + /* 2266 */ { MAD_F(0x0744337a) /* 0.454150653 */, 16 }, + /* 2267 */ { MAD_F(0x07454bb4) /* 0.454417899 */, 16 }, + /* 2268 */ { MAD_F(0x074663f8) /* 0.454685184 */, 16 }, + /* 2269 */ { MAD_F(0x07477c48) /* 0.454952508 */, 16 }, + /* 2270 */ { MAD_F(0x074894a2) /* 0.455219872 */, 16 }, + /* 2271 */ { MAD_F(0x0749ad06) /* 0.455487275 */, 16 }, + + /* 2272 */ { MAD_F(0x074ac575) /* 0.455754717 */, 16 }, + /* 2273 */ { MAD_F(0x074bddee) /* 0.456022198 */, 16 }, + /* 2274 */ { MAD_F(0x074cf672) /* 0.456289719 */, 16 }, + /* 2275 */ { MAD_F(0x074e0f01) /* 0.456557278 */, 16 }, + /* 2276 */ { MAD_F(0x074f279a) /* 0.456824877 */, 16 }, + /* 2277 */ { MAD_F(0x0750403e) /* 0.457092516 */, 16 }, + /* 2278 */ { MAD_F(0x075158ec) /* 0.457360193 */, 16 }, + /* 2279 */ { MAD_F(0x075271a4) /* 0.457627909 */, 16 }, + /* 2280 */ { MAD_F(0x07538a67) /* 0.457895665 */, 16 }, + /* 2281 */ { MAD_F(0x0754a335) /* 0.458163460 */, 16 }, + /* 2282 */ { MAD_F(0x0755bc0d) /* 0.458431294 */, 16 }, + /* 2283 */ { MAD_F(0x0756d4f0) /* 0.458699167 */, 16 }, + /* 2284 */ { MAD_F(0x0757eddd) /* 0.458967079 */, 16 }, + /* 2285 */ { MAD_F(0x075906d5) /* 0.459235030 */, 16 }, + /* 2286 */ { MAD_F(0x075a1fd7) /* 0.459503021 */, 16 }, + /* 2287 */ { MAD_F(0x075b38e3) /* 0.459771050 */, 16 }, + + /* 2288 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 16 }, + /* 2289 */ { MAD_F(0x075d6b1c) /* 0.460307226 */, 16 }, + /* 2290 */ { MAD_F(0x075e8448) /* 0.460575373 */, 16 }, + /* 2291 */ { MAD_F(0x075f9d7f) /* 0.460843559 */, 16 }, + /* 2292 */ { MAD_F(0x0760b6c0) /* 0.461111783 */, 16 }, + /* 2293 */ { MAD_F(0x0761d00b) /* 0.461380047 */, 16 }, + /* 2294 */ { MAD_F(0x0762e961) /* 0.461648350 */, 16 }, + /* 2295 */ { MAD_F(0x076402c1) /* 0.461916691 */, 16 }, + /* 2296 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 16 }, + /* 2297 */ { MAD_F(0x076635a2) /* 0.462453492 */, 16 }, + /* 2298 */ { MAD_F(0x07674f22) /* 0.462721950 */, 16 }, + /* 2299 */ { MAD_F(0x076868ac) /* 0.462990448 */, 16 }, + /* 2300 */ { MAD_F(0x07698240) /* 0.463258984 */, 16 }, + /* 2301 */ { MAD_F(0x076a9be0) /* 0.463527560 */, 16 }, + /* 2302 */ { MAD_F(0x076bb589) /* 0.463796174 */, 16 }, + /* 2303 */ { MAD_F(0x076ccf3d) /* 0.464064827 */, 16 }, + + /* 2304 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 16 }, + /* 2305 */ { MAD_F(0x076f02c5) /* 0.464602250 */, 16 }, + /* 2306 */ { MAD_F(0x07701c98) /* 0.464871020 */, 16 }, + /* 2307 */ { MAD_F(0x07713676) /* 0.465139829 */, 16 }, + /* 2308 */ { MAD_F(0x0772505e) /* 0.465408676 */, 16 }, + /* 2309 */ { MAD_F(0x07736a51) /* 0.465677563 */, 16 }, + /* 2310 */ { MAD_F(0x0774844e) /* 0.465946488 */, 16 }, + /* 2311 */ { MAD_F(0x07759e55) /* 0.466215452 */, 16 }, + /* 2312 */ { MAD_F(0x0776b867) /* 0.466484455 */, 16 }, + /* 2313 */ { MAD_F(0x0777d283) /* 0.466753496 */, 16 }, + /* 2314 */ { MAD_F(0x0778ecaa) /* 0.467022577 */, 16 }, + /* 2315 */ { MAD_F(0x077a06db) /* 0.467291696 */, 16 }, + /* 2316 */ { MAD_F(0x077b2117) /* 0.467560854 */, 16 }, + /* 2317 */ { MAD_F(0x077c3b5d) /* 0.467830050 */, 16 }, + /* 2318 */ { MAD_F(0x077d55ad) /* 0.468099285 */, 16 }, + /* 2319 */ { MAD_F(0x077e7008) /* 0.468368560 */, 16 }, + + /* 2320 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 16 }, + /* 2321 */ { MAD_F(0x0780a4dc) /* 0.468907224 */, 16 }, + /* 2322 */ { MAD_F(0x0781bf56) /* 0.469176614 */, 16 }, + /* 2323 */ { MAD_F(0x0782d9da) /* 0.469446043 */, 16 }, + /* 2324 */ { MAD_F(0x0783f469) /* 0.469715510 */, 16 }, + /* 2325 */ { MAD_F(0x07850f02) /* 0.469985016 */, 16 }, + /* 2326 */ { MAD_F(0x078629a5) /* 0.470254561 */, 16 }, + /* 2327 */ { MAD_F(0x07874453) /* 0.470524145 */, 16 }, + /* 2328 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 16 }, + /* 2329 */ { MAD_F(0x078979ce) /* 0.471063427 */, 16 }, + /* 2330 */ { MAD_F(0x078a949a) /* 0.471333126 */, 16 }, + /* 2331 */ { MAD_F(0x078baf72) /* 0.471602864 */, 16 }, + /* 2332 */ { MAD_F(0x078cca53) /* 0.471872641 */, 16 }, + /* 2333 */ { MAD_F(0x078de53f) /* 0.472142456 */, 16 }, + /* 2334 */ { MAD_F(0x078f0035) /* 0.472412309 */, 16 }, + /* 2335 */ { MAD_F(0x07901b36) /* 0.472682201 */, 16 }, + + /* 2336 */ { MAD_F(0x07913641) /* 0.472952132 */, 16 }, + /* 2337 */ { MAD_F(0x07925156) /* 0.473222101 */, 16 }, + /* 2338 */ { MAD_F(0x07936c76) /* 0.473492108 */, 16 }, + /* 2339 */ { MAD_F(0x079487a0) /* 0.473762155 */, 16 }, + /* 2340 */ { MAD_F(0x0795a2d4) /* 0.474032239 */, 16 }, + /* 2341 */ { MAD_F(0x0796be13) /* 0.474302362 */, 16 }, + /* 2342 */ { MAD_F(0x0797d95c) /* 0.474572524 */, 16 }, + /* 2343 */ { MAD_F(0x0798f4af) /* 0.474842724 */, 16 }, + /* 2344 */ { MAD_F(0x079a100c) /* 0.475112962 */, 16 }, + /* 2345 */ { MAD_F(0x079b2b74) /* 0.475383239 */, 16 }, + /* 2346 */ { MAD_F(0x079c46e7) /* 0.475653554 */, 16 }, + /* 2347 */ { MAD_F(0x079d6263) /* 0.475923908 */, 16 }, + /* 2348 */ { MAD_F(0x079e7dea) /* 0.476194300 */, 16 }, + /* 2349 */ { MAD_F(0x079f997b) /* 0.476464731 */, 16 }, + /* 2350 */ { MAD_F(0x07a0b516) /* 0.476735200 */, 16 }, + /* 2351 */ { MAD_F(0x07a1d0bc) /* 0.477005707 */, 16 }, + + /* 2352 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 16 }, + /* 2353 */ { MAD_F(0x07a40827) /* 0.477546836 */, 16 }, + /* 2354 */ { MAD_F(0x07a523eb) /* 0.477817459 */, 16 }, + /* 2355 */ { MAD_F(0x07a63fba) /* 0.478088119 */, 16 }, + /* 2356 */ { MAD_F(0x07a75b93) /* 0.478358818 */, 16 }, + /* 2357 */ { MAD_F(0x07a87777) /* 0.478629555 */, 16 }, + /* 2358 */ { MAD_F(0x07a99364) /* 0.478900331 */, 16 }, + /* 2359 */ { MAD_F(0x07aaaf5c) /* 0.479171145 */, 16 }, + /* 2360 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 16 }, + /* 2361 */ { MAD_F(0x07ace76b) /* 0.479712887 */, 16 }, + /* 2362 */ { MAD_F(0x07ae0382) /* 0.479983816 */, 16 }, + /* 2363 */ { MAD_F(0x07af1fa3) /* 0.480254782 */, 16 }, + /* 2364 */ { MAD_F(0x07b03bcf) /* 0.480525787 */, 16 }, + /* 2365 */ { MAD_F(0x07b15804) /* 0.480796831 */, 16 }, + /* 2366 */ { MAD_F(0x07b27444) /* 0.481067912 */, 16 }, + /* 2367 */ { MAD_F(0x07b3908e) /* 0.481339032 */, 16 }, + + /* 2368 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 16 }, + /* 2369 */ { MAD_F(0x07b5c941) /* 0.481881385 */, 16 }, + /* 2370 */ { MAD_F(0x07b6e5aa) /* 0.482152620 */, 16 }, + /* 2371 */ { MAD_F(0x07b8021d) /* 0.482423892 */, 16 }, + /* 2372 */ { MAD_F(0x07b91e9b) /* 0.482695202 */, 16 }, + /* 2373 */ { MAD_F(0x07ba3b22) /* 0.482966551 */, 16 }, + /* 2374 */ { MAD_F(0x07bb57b4) /* 0.483237938 */, 16 }, + /* 2375 */ { MAD_F(0x07bc7450) /* 0.483509362 */, 16 }, + /* 2376 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 16 }, + /* 2377 */ { MAD_F(0x07beada7) /* 0.484052326 */, 16 }, + /* 2378 */ { MAD_F(0x07bfca61) /* 0.484323865 */, 16 }, + /* 2379 */ { MAD_F(0x07c0e726) /* 0.484595443 */, 16 }, + /* 2380 */ { MAD_F(0x07c203f5) /* 0.484867058 */, 16 }, + /* 2381 */ { MAD_F(0x07c320cf) /* 0.485138711 */, 16 }, + /* 2382 */ { MAD_F(0x07c43db2) /* 0.485410402 */, 16 }, + /* 2383 */ { MAD_F(0x07c55aa0) /* 0.485682131 */, 16 }, + + /* 2384 */ { MAD_F(0x07c67798) /* 0.485953899 */, 16 }, + /* 2385 */ { MAD_F(0x07c7949a) /* 0.486225704 */, 16 }, + /* 2386 */ { MAD_F(0x07c8b1a7) /* 0.486497547 */, 16 }, + /* 2387 */ { MAD_F(0x07c9cebd) /* 0.486769429 */, 16 }, + /* 2388 */ { MAD_F(0x07caebde) /* 0.487041348 */, 16 }, + /* 2389 */ { MAD_F(0x07cc0909) /* 0.487313305 */, 16 }, + /* 2390 */ { MAD_F(0x07cd263e) /* 0.487585300 */, 16 }, + /* 2391 */ { MAD_F(0x07ce437d) /* 0.487857333 */, 16 }, + /* 2392 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 16 }, + /* 2393 */ { MAD_F(0x07d07e1b) /* 0.488401513 */, 16 }, + /* 2394 */ { MAD_F(0x07d19b79) /* 0.488673660 */, 16 }, + /* 2395 */ { MAD_F(0x07d2b8e1) /* 0.488945845 */, 16 }, + /* 2396 */ { MAD_F(0x07d3d653) /* 0.489218067 */, 16 }, + /* 2397 */ { MAD_F(0x07d4f3cf) /* 0.489490328 */, 16 }, + /* 2398 */ { MAD_F(0x07d61156) /* 0.489762626 */, 16 }, + /* 2399 */ { MAD_F(0x07d72ee6) /* 0.490034962 */, 16 }, + + /* 2400 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 16 }, + /* 2401 */ { MAD_F(0x07d96a26) /* 0.490579748 */, 16 }, + /* 2402 */ { MAD_F(0x07da87d5) /* 0.490852198 */, 16 }, + /* 2403 */ { MAD_F(0x07dba58f) /* 0.491124686 */, 16 }, + /* 2404 */ { MAD_F(0x07dcc352) /* 0.491397211 */, 16 }, + /* 2405 */ { MAD_F(0x07dde120) /* 0.491669774 */, 16 }, + /* 2406 */ { MAD_F(0x07defef7) /* 0.491942375 */, 16 }, + /* 2407 */ { MAD_F(0x07e01cd9) /* 0.492215014 */, 16 }, + /* 2408 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 16 }, + /* 2409 */ { MAD_F(0x07e258bc) /* 0.492760404 */, 16 }, + /* 2410 */ { MAD_F(0x07e376bc) /* 0.493033156 */, 16 }, + /* 2411 */ { MAD_F(0x07e494c6) /* 0.493305946 */, 16 }, + /* 2412 */ { MAD_F(0x07e5b2db) /* 0.493578773 */, 16 }, + /* 2413 */ { MAD_F(0x07e6d0f9) /* 0.493851638 */, 16 }, + /* 2414 */ { MAD_F(0x07e7ef22) /* 0.494124541 */, 16 }, + /* 2415 */ { MAD_F(0x07e90d55) /* 0.494397481 */, 16 }, + + /* 2416 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 16 }, + /* 2417 */ { MAD_F(0x07eb49d9) /* 0.494943475 */, 16 }, + /* 2418 */ { MAD_F(0x07ec682a) /* 0.495216529 */, 16 }, + /* 2419 */ { MAD_F(0x07ed8686) /* 0.495489620 */, 16 }, + /* 2420 */ { MAD_F(0x07eea4eb) /* 0.495762748 */, 16 }, + /* 2421 */ { MAD_F(0x07efc35b) /* 0.496035915 */, 16 }, + /* 2422 */ { MAD_F(0x07f0e1d4) /* 0.496309119 */, 16 }, + /* 2423 */ { MAD_F(0x07f20058) /* 0.496582360 */, 16 }, + /* 2424 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 16 }, + /* 2425 */ { MAD_F(0x07f43d7e) /* 0.497128956 */, 16 }, + /* 2426 */ { MAD_F(0x07f55c20) /* 0.497402310 */, 16 }, + /* 2427 */ { MAD_F(0x07f67acc) /* 0.497675702 */, 16 }, + /* 2428 */ { MAD_F(0x07f79982) /* 0.497949132 */, 16 }, + /* 2429 */ { MAD_F(0x07f8b842) /* 0.498222598 */, 16 }, + /* 2430 */ { MAD_F(0x07f9d70c) /* 0.498496103 */, 16 }, + /* 2431 */ { MAD_F(0x07faf5e1) /* 0.498769645 */, 16 }, + + /* 2432 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 16 }, + /* 2433 */ { MAD_F(0x07fd33a8) /* 0.499316841 */, 16 }, + /* 2434 */ { MAD_F(0x07fe529a) /* 0.499590496 */, 16 }, + /* 2435 */ { MAD_F(0x07ff7197) /* 0.499864188 */, 16 }, + /* 2436 */ { MAD_F(0x0400484f) /* 0.250068959 */, 17 }, + /* 2437 */ { MAD_F(0x0400d7d7) /* 0.250205842 */, 17 }, + /* 2438 */ { MAD_F(0x04016764) /* 0.250342744 */, 17 }, + /* 2439 */ { MAD_F(0x0401f6f7) /* 0.250479665 */, 17 }, + /* 2440 */ { MAD_F(0x0402868e) /* 0.250616605 */, 17 }, + /* 2441 */ { MAD_F(0x0403162b) /* 0.250753563 */, 17 }, + /* 2442 */ { MAD_F(0x0403a5cc) /* 0.250890540 */, 17 }, + /* 2443 */ { MAD_F(0x04043573) /* 0.251027536 */, 17 }, + /* 2444 */ { MAD_F(0x0404c51e) /* 0.251164550 */, 17 }, + /* 2445 */ { MAD_F(0x040554cf) /* 0.251301583 */, 17 }, + /* 2446 */ { MAD_F(0x0405e484) /* 0.251438635 */, 17 }, + /* 2447 */ { MAD_F(0x0406743f) /* 0.251575706 */, 17 }, + + /* 2448 */ { MAD_F(0x040703ff) /* 0.251712795 */, 17 }, + /* 2449 */ { MAD_F(0x040793c3) /* 0.251849903 */, 17 }, + /* 2450 */ { MAD_F(0x0408238d) /* 0.251987029 */, 17 }, + /* 2451 */ { MAD_F(0x0408b35b) /* 0.252124174 */, 17 }, + /* 2452 */ { MAD_F(0x0409432f) /* 0.252261338 */, 17 }, + /* 2453 */ { MAD_F(0x0409d308) /* 0.252398520 */, 17 }, + /* 2454 */ { MAD_F(0x040a62e5) /* 0.252535721 */, 17 }, + /* 2455 */ { MAD_F(0x040af2c8) /* 0.252672941 */, 17 }, + /* 2456 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 17 }, + /* 2457 */ { MAD_F(0x040c129c) /* 0.252947436 */, 17 }, + /* 2458 */ { MAD_F(0x040ca28e) /* 0.253084712 */, 17 }, + /* 2459 */ { MAD_F(0x040d3284) /* 0.253222006 */, 17 }, + /* 2460 */ { MAD_F(0x040dc280) /* 0.253359319 */, 17 }, + /* 2461 */ { MAD_F(0x040e5281) /* 0.253496651 */, 17 }, + /* 2462 */ { MAD_F(0x040ee286) /* 0.253634001 */, 17 }, + /* 2463 */ { MAD_F(0x040f7291) /* 0.253771369 */, 17 }, + + /* 2464 */ { MAD_F(0x041002a1) /* 0.253908756 */, 17 }, + /* 2465 */ { MAD_F(0x041092b5) /* 0.254046162 */, 17 }, + /* 2466 */ { MAD_F(0x041122cf) /* 0.254183587 */, 17 }, + /* 2467 */ { MAD_F(0x0411b2ed) /* 0.254321030 */, 17 }, + /* 2468 */ { MAD_F(0x04124311) /* 0.254458491 */, 17 }, + /* 2469 */ { MAD_F(0x0412d339) /* 0.254595971 */, 17 }, + /* 2470 */ { MAD_F(0x04136367) /* 0.254733470 */, 17 }, + /* 2471 */ { MAD_F(0x0413f399) /* 0.254870987 */, 17 }, + /* 2472 */ { MAD_F(0x041483d1) /* 0.255008523 */, 17 }, + /* 2473 */ { MAD_F(0x0415140d) /* 0.255146077 */, 17 }, + /* 2474 */ { MAD_F(0x0415a44f) /* 0.255283650 */, 17 }, + /* 2475 */ { MAD_F(0x04163495) /* 0.255421241 */, 17 }, + /* 2476 */ { MAD_F(0x0416c4e1) /* 0.255558851 */, 17 }, + /* 2477 */ { MAD_F(0x04175531) /* 0.255696480 */, 17 }, + /* 2478 */ { MAD_F(0x0417e586) /* 0.255834127 */, 17 }, + /* 2479 */ { MAD_F(0x041875e1) /* 0.255971792 */, 17 }, + + /* 2480 */ { MAD_F(0x04190640) /* 0.256109476 */, 17 }, + /* 2481 */ { MAD_F(0x041996a4) /* 0.256247179 */, 17 }, + /* 2482 */ { MAD_F(0x041a270d) /* 0.256384900 */, 17 }, + /* 2483 */ { MAD_F(0x041ab77b) /* 0.256522639 */, 17 }, + /* 2484 */ { MAD_F(0x041b47ef) /* 0.256660397 */, 17 }, + /* 2485 */ { MAD_F(0x041bd867) /* 0.256798174 */, 17 }, + /* 2486 */ { MAD_F(0x041c68e4) /* 0.256935969 */, 17 }, + /* 2487 */ { MAD_F(0x041cf966) /* 0.257073782 */, 17 }, + /* 2488 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 17 }, + /* 2489 */ { MAD_F(0x041e1a79) /* 0.257349465 */, 17 }, + /* 2490 */ { MAD_F(0x041eab0a) /* 0.257487334 */, 17 }, + /* 2491 */ { MAD_F(0x041f3b9f) /* 0.257625221 */, 17 }, + /* 2492 */ { MAD_F(0x041fcc3a) /* 0.257763127 */, 17 }, + /* 2493 */ { MAD_F(0x04205cda) /* 0.257901051 */, 17 }, + /* 2494 */ { MAD_F(0x0420ed7f) /* 0.258038994 */, 17 }, + /* 2495 */ { MAD_F(0x04217e28) /* 0.258176955 */, 17 }, + + /* 2496 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 17 }, + /* 2497 */ { MAD_F(0x04229f8a) /* 0.258452932 */, 17 }, + /* 2498 */ { MAD_F(0x04233043) /* 0.258590948 */, 17 }, + /* 2499 */ { MAD_F(0x0423c100) /* 0.258728983 */, 17 }, + /* 2500 */ { MAD_F(0x042451c3) /* 0.258867036 */, 17 }, + /* 2501 */ { MAD_F(0x0424e28a) /* 0.259005108 */, 17 }, + /* 2502 */ { MAD_F(0x04257356) /* 0.259143198 */, 17 }, + /* 2503 */ { MAD_F(0x04260428) /* 0.259281307 */, 17 }, + /* 2504 */ { MAD_F(0x042694fe) /* 0.259419433 */, 17 }, + /* 2505 */ { MAD_F(0x042725d9) /* 0.259557579 */, 17 }, + /* 2506 */ { MAD_F(0x0427b6b9) /* 0.259695742 */, 17 }, + /* 2507 */ { MAD_F(0x0428479e) /* 0.259833924 */, 17 }, + /* 2508 */ { MAD_F(0x0428d888) /* 0.259972124 */, 17 }, + /* 2509 */ { MAD_F(0x04296976) /* 0.260110343 */, 17 }, + /* 2510 */ { MAD_F(0x0429fa6a) /* 0.260248580 */, 17 }, + /* 2511 */ { MAD_F(0x042a8b63) /* 0.260386836 */, 17 }, + + /* 2512 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 17 }, + /* 2513 */ { MAD_F(0x042bad63) /* 0.260663402 */, 17 }, + /* 2514 */ { MAD_F(0x042c3e6a) /* 0.260801712 */, 17 }, + /* 2515 */ { MAD_F(0x042ccf77) /* 0.260940041 */, 17 }, + /* 2516 */ { MAD_F(0x042d6088) /* 0.261078388 */, 17 }, + /* 2517 */ { MAD_F(0x042df19e) /* 0.261216754 */, 17 }, + /* 2518 */ { MAD_F(0x042e82b9) /* 0.261355137 */, 17 }, + /* 2519 */ { MAD_F(0x042f13d9) /* 0.261493540 */, 17 }, + /* 2520 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 17 }, + /* 2521 */ { MAD_F(0x04303628) /* 0.261770399 */, 17 }, + /* 2522 */ { MAD_F(0x0430c757) /* 0.261908856 */, 17 }, + /* 2523 */ { MAD_F(0x0431588b) /* 0.262047331 */, 17 }, + /* 2524 */ { MAD_F(0x0431e9c3) /* 0.262185825 */, 17 }, + /* 2525 */ { MAD_F(0x04327b01) /* 0.262324337 */, 17 }, + /* 2526 */ { MAD_F(0x04330c43) /* 0.262462867 */, 17 }, + /* 2527 */ { MAD_F(0x04339d8a) /* 0.262601416 */, 17 }, + + /* 2528 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 17 }, + /* 2529 */ { MAD_F(0x0434c028) /* 0.262878568 */, 17 }, + /* 2530 */ { MAD_F(0x0435517e) /* 0.263017171 */, 17 }, + /* 2531 */ { MAD_F(0x0435e2d9) /* 0.263155792 */, 17 }, + /* 2532 */ { MAD_F(0x04367439) /* 0.263294432 */, 17 }, + /* 2533 */ { MAD_F(0x0437059e) /* 0.263433090 */, 17 }, + /* 2534 */ { MAD_F(0x04379707) /* 0.263571767 */, 17 }, + /* 2535 */ { MAD_F(0x04382876) /* 0.263710461 */, 17 }, + /* 2536 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 17 }, + /* 2537 */ { MAD_F(0x04394b61) /* 0.263987905 */, 17 }, + /* 2538 */ { MAD_F(0x0439dcdf) /* 0.264126655 */, 17 }, + /* 2539 */ { MAD_F(0x043a6e61) /* 0.264265422 */, 17 }, + /* 2540 */ { MAD_F(0x043affe8) /* 0.264404208 */, 17 }, + /* 2541 */ { MAD_F(0x043b9174) /* 0.264543012 */, 17 }, + /* 2542 */ { MAD_F(0x043c2305) /* 0.264681834 */, 17 }, + /* 2543 */ { MAD_F(0x043cb49a) /* 0.264820674 */, 17 }, + + /* 2544 */ { MAD_F(0x043d4635) /* 0.264959533 */, 17 }, + /* 2545 */ { MAD_F(0x043dd7d4) /* 0.265098410 */, 17 }, + /* 2546 */ { MAD_F(0x043e6979) /* 0.265237305 */, 17 }, + /* 2547 */ { MAD_F(0x043efb22) /* 0.265376218 */, 17 }, + /* 2548 */ { MAD_F(0x043f8cd0) /* 0.265515149 */, 17 }, + /* 2549 */ { MAD_F(0x04401e83) /* 0.265654099 */, 17 }, + /* 2550 */ { MAD_F(0x0440b03b) /* 0.265793066 */, 17 }, + /* 2551 */ { MAD_F(0x044141f7) /* 0.265932052 */, 17 }, + /* 2552 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 17 }, + /* 2553 */ { MAD_F(0x04426580) /* 0.266210078 */, 17 }, + /* 2554 */ { MAD_F(0x0442f74b) /* 0.266349119 */, 17 }, + /* 2555 */ { MAD_F(0x0443891b) /* 0.266488177 */, 17 }, + /* 2556 */ { MAD_F(0x04441af0) /* 0.266627254 */, 17 }, + /* 2557 */ { MAD_F(0x0444acca) /* 0.266766349 */, 17 }, + /* 2558 */ { MAD_F(0x04453ea9) /* 0.266905462 */, 17 }, + /* 2559 */ { MAD_F(0x0445d08d) /* 0.267044593 */, 17 }, + + /* 2560 */ { MAD_F(0x04466275) /* 0.267183742 */, 17 }, + /* 2561 */ { MAD_F(0x0446f463) /* 0.267322909 */, 17 }, + /* 2562 */ { MAD_F(0x04478655) /* 0.267462094 */, 17 }, + /* 2563 */ { MAD_F(0x0448184c) /* 0.267601298 */, 17 }, + /* 2564 */ { MAD_F(0x0448aa48) /* 0.267740519 */, 17 }, + /* 2565 */ { MAD_F(0x04493c49) /* 0.267879759 */, 17 }, + /* 2566 */ { MAD_F(0x0449ce4f) /* 0.268019017 */, 17 }, + /* 2567 */ { MAD_F(0x044a6059) /* 0.268158293 */, 17 }, + /* 2568 */ { MAD_F(0x044af269) /* 0.268297587 */, 17 }, + /* 2569 */ { MAD_F(0x044b847d) /* 0.268436899 */, 17 }, + /* 2570 */ { MAD_F(0x044c1696) /* 0.268576229 */, 17 }, + /* 2571 */ { MAD_F(0x044ca8b4) /* 0.268715577 */, 17 }, + /* 2572 */ { MAD_F(0x044d3ad7) /* 0.268854943 */, 17 }, + /* 2573 */ { MAD_F(0x044dccff) /* 0.268994328 */, 17 }, + /* 2574 */ { MAD_F(0x044e5f2b) /* 0.269133730 */, 17 }, + /* 2575 */ { MAD_F(0x044ef15d) /* 0.269273150 */, 17 }, + + /* 2576 */ { MAD_F(0x044f8393) /* 0.269412589 */, 17 }, + /* 2577 */ { MAD_F(0x045015ce) /* 0.269552045 */, 17 }, + /* 2578 */ { MAD_F(0x0450a80e) /* 0.269691520 */, 17 }, + /* 2579 */ { MAD_F(0x04513a53) /* 0.269831013 */, 17 }, + /* 2580 */ { MAD_F(0x0451cc9c) /* 0.269970523 */, 17 }, + /* 2581 */ { MAD_F(0x04525eeb) /* 0.270110052 */, 17 }, + /* 2582 */ { MAD_F(0x0452f13e) /* 0.270249599 */, 17 }, + /* 2583 */ { MAD_F(0x04538396) /* 0.270389163 */, 17 }, + /* 2584 */ { MAD_F(0x045415f3) /* 0.270528746 */, 17 }, + /* 2585 */ { MAD_F(0x0454a855) /* 0.270668347 */, 17 }, + /* 2586 */ { MAD_F(0x04553abb) /* 0.270807965 */, 17 }, + /* 2587 */ { MAD_F(0x0455cd27) /* 0.270947602 */, 17 }, + /* 2588 */ { MAD_F(0x04565f97) /* 0.271087257 */, 17 }, + /* 2589 */ { MAD_F(0x0456f20c) /* 0.271226930 */, 17 }, + /* 2590 */ { MAD_F(0x04578486) /* 0.271366620 */, 17 }, + /* 2591 */ { MAD_F(0x04581705) /* 0.271506329 */, 17 }, + + /* 2592 */ { MAD_F(0x0458a989) /* 0.271646056 */, 17 }, + /* 2593 */ { MAD_F(0x04593c11) /* 0.271785800 */, 17 }, + /* 2594 */ { MAD_F(0x0459ce9e) /* 0.271925563 */, 17 }, + /* 2595 */ { MAD_F(0x045a6130) /* 0.272065343 */, 17 }, + /* 2596 */ { MAD_F(0x045af3c7) /* 0.272205142 */, 17 }, + /* 2597 */ { MAD_F(0x045b8663) /* 0.272344958 */, 17 }, + /* 2598 */ { MAD_F(0x045c1903) /* 0.272484793 */, 17 }, + /* 2599 */ { MAD_F(0x045caba9) /* 0.272624645 */, 17 }, + /* 2600 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 17 }, + /* 2601 */ { MAD_F(0x045dd102) /* 0.272904403 */, 17 }, + /* 2602 */ { MAD_F(0x045e63b6) /* 0.273044310 */, 17 }, + /* 2603 */ { MAD_F(0x045ef66e) /* 0.273184234 */, 17 }, + /* 2604 */ { MAD_F(0x045f892b) /* 0.273324176 */, 17 }, + /* 2605 */ { MAD_F(0x04601bee) /* 0.273464136 */, 17 }, + /* 2606 */ { MAD_F(0x0460aeb5) /* 0.273604113 */, 17 }, + /* 2607 */ { MAD_F(0x04614180) /* 0.273744109 */, 17 }, + + /* 2608 */ { MAD_F(0x0461d451) /* 0.273884123 */, 17 }, + /* 2609 */ { MAD_F(0x04626727) /* 0.274024154 */, 17 }, + /* 2610 */ { MAD_F(0x0462fa01) /* 0.274164204 */, 17 }, + /* 2611 */ { MAD_F(0x04638ce0) /* 0.274304271 */, 17 }, + /* 2612 */ { MAD_F(0x04641fc4) /* 0.274444356 */, 17 }, + /* 2613 */ { MAD_F(0x0464b2ac) /* 0.274584459 */, 17 }, + /* 2614 */ { MAD_F(0x0465459a) /* 0.274724580 */, 17 }, + /* 2615 */ { MAD_F(0x0465d88c) /* 0.274864719 */, 17 }, + /* 2616 */ { MAD_F(0x04666b83) /* 0.275004875 */, 17 }, + /* 2617 */ { MAD_F(0x0466fe7f) /* 0.275145050 */, 17 }, + /* 2618 */ { MAD_F(0x0467917f) /* 0.275285242 */, 17 }, + /* 2619 */ { MAD_F(0x04682485) /* 0.275425452 */, 17 }, + /* 2620 */ { MAD_F(0x0468b78f) /* 0.275565681 */, 17 }, + /* 2621 */ { MAD_F(0x04694a9e) /* 0.275705926 */, 17 }, + /* 2622 */ { MAD_F(0x0469ddb2) /* 0.275846190 */, 17 }, + /* 2623 */ { MAD_F(0x046a70ca) /* 0.275986472 */, 17 }, + + /* 2624 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 17 }, + /* 2625 */ { MAD_F(0x046b970a) /* 0.276267088 */, 17 }, + /* 2626 */ { MAD_F(0x046c2a31) /* 0.276407423 */, 17 }, + /* 2627 */ { MAD_F(0x046cbd5c) /* 0.276547776 */, 17 }, + /* 2628 */ { MAD_F(0x046d508d) /* 0.276688147 */, 17 }, + /* 2629 */ { MAD_F(0x046de3c2) /* 0.276828535 */, 17 }, + /* 2630 */ { MAD_F(0x046e76fc) /* 0.276968942 */, 17 }, + /* 2631 */ { MAD_F(0x046f0a3b) /* 0.277109366 */, 17 }, + /* 2632 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 17 }, + /* 2633 */ { MAD_F(0x047030c7) /* 0.277390267 */, 17 }, + /* 2634 */ { MAD_F(0x0470c414) /* 0.277530745 */, 17 }, + /* 2635 */ { MAD_F(0x04715766) /* 0.277671240 */, 17 }, + /* 2636 */ { MAD_F(0x0471eabc) /* 0.277811753 */, 17 }, + /* 2637 */ { MAD_F(0x04727e18) /* 0.277952284 */, 17 }, + /* 2638 */ { MAD_F(0x04731178) /* 0.278092832 */, 17 }, + /* 2639 */ { MAD_F(0x0473a4dd) /* 0.278233399 */, 17 }, + + /* 2640 */ { MAD_F(0x04743847) /* 0.278373983 */, 17 }, + /* 2641 */ { MAD_F(0x0474cbb5) /* 0.278514584 */, 17 }, + /* 2642 */ { MAD_F(0x04755f29) /* 0.278655204 */, 17 }, + /* 2643 */ { MAD_F(0x0475f2a1) /* 0.278795841 */, 17 }, + /* 2644 */ { MAD_F(0x0476861d) /* 0.278936496 */, 17 }, + /* 2645 */ { MAD_F(0x0477199f) /* 0.279077169 */, 17 }, + /* 2646 */ { MAD_F(0x0477ad25) /* 0.279217860 */, 17 }, + /* 2647 */ { MAD_F(0x047840b0) /* 0.279358568 */, 17 }, + /* 2648 */ { MAD_F(0x0478d440) /* 0.279499294 */, 17 }, + /* 2649 */ { MAD_F(0x047967d5) /* 0.279640037 */, 17 }, + /* 2650 */ { MAD_F(0x0479fb6e) /* 0.279780799 */, 17 }, + /* 2651 */ { MAD_F(0x047a8f0c) /* 0.279921578 */, 17 }, + /* 2652 */ { MAD_F(0x047b22af) /* 0.280062375 */, 17 }, + /* 2653 */ { MAD_F(0x047bb657) /* 0.280203189 */, 17 }, + /* 2654 */ { MAD_F(0x047c4a03) /* 0.280344021 */, 17 }, + /* 2655 */ { MAD_F(0x047cddb4) /* 0.280484871 */, 17 }, + + /* 2656 */ { MAD_F(0x047d716a) /* 0.280625739 */, 17 }, + /* 2657 */ { MAD_F(0x047e0524) /* 0.280766624 */, 17 }, + /* 2658 */ { MAD_F(0x047e98e4) /* 0.280907527 */, 17 }, + /* 2659 */ { MAD_F(0x047f2ca8) /* 0.281048447 */, 17 }, + /* 2660 */ { MAD_F(0x047fc071) /* 0.281189385 */, 17 }, + /* 2661 */ { MAD_F(0x0480543e) /* 0.281330341 */, 17 }, + /* 2662 */ { MAD_F(0x0480e811) /* 0.281471315 */, 17 }, + /* 2663 */ { MAD_F(0x04817be8) /* 0.281612306 */, 17 }, + /* 2664 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 17 }, + /* 2665 */ { MAD_F(0x0482a3a4) /* 0.281894341 */, 17 }, + /* 2666 */ { MAD_F(0x04833789) /* 0.282035386 */, 17 }, + /* 2667 */ { MAD_F(0x0483cb73) /* 0.282176447 */, 17 }, + /* 2668 */ { MAD_F(0x04845f62) /* 0.282317527 */, 17 }, + /* 2669 */ { MAD_F(0x0484f355) /* 0.282458624 */, 17 }, + /* 2670 */ { MAD_F(0x0485874d) /* 0.282599738 */, 17 }, + /* 2671 */ { MAD_F(0x04861b4a) /* 0.282740871 */, 17 }, + + /* 2672 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 17 }, + /* 2673 */ { MAD_F(0x04874352) /* 0.283023188 */, 17 }, + /* 2674 */ { MAD_F(0x0487d75d) /* 0.283164373 */, 17 }, + /* 2675 */ { MAD_F(0x04886b6d) /* 0.283305576 */, 17 }, + /* 2676 */ { MAD_F(0x0488ff82) /* 0.283446796 */, 17 }, + /* 2677 */ { MAD_F(0x0489939b) /* 0.283588034 */, 17 }, + /* 2678 */ { MAD_F(0x048a27b9) /* 0.283729290 */, 17 }, + /* 2679 */ { MAD_F(0x048abbdc) /* 0.283870563 */, 17 }, + /* 2680 */ { MAD_F(0x048b5003) /* 0.284011853 */, 17 }, + /* 2681 */ { MAD_F(0x048be42f) /* 0.284153161 */, 17 }, + /* 2682 */ { MAD_F(0x048c7860) /* 0.284294487 */, 17 }, + /* 2683 */ { MAD_F(0x048d0c96) /* 0.284435831 */, 17 }, + /* 2684 */ { MAD_F(0x048da0d0) /* 0.284577192 */, 17 }, + /* 2685 */ { MAD_F(0x048e350f) /* 0.284718570 */, 17 }, + /* 2686 */ { MAD_F(0x048ec953) /* 0.284859966 */, 17 }, + /* 2687 */ { MAD_F(0x048f5d9b) /* 0.285001380 */, 17 }, + + /* 2688 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 17 }, + /* 2689 */ { MAD_F(0x0490863a) /* 0.285284259 */, 17 }, + /* 2690 */ { MAD_F(0x04911a91) /* 0.285425726 */, 17 }, + /* 2691 */ { MAD_F(0x0491aeec) /* 0.285567209 */, 17 }, + /* 2692 */ { MAD_F(0x0492434c) /* 0.285708711 */, 17 }, + /* 2693 */ { MAD_F(0x0492d7b0) /* 0.285850229 */, 17 }, + /* 2694 */ { MAD_F(0x04936c1a) /* 0.285991766 */, 17 }, + /* 2695 */ { MAD_F(0x04940088) /* 0.286133319 */, 17 }, + /* 2696 */ { MAD_F(0x049494fb) /* 0.286274891 */, 17 }, + /* 2697 */ { MAD_F(0x04952972) /* 0.286416480 */, 17 }, + /* 2698 */ { MAD_F(0x0495bdee) /* 0.286558086 */, 17 }, + /* 2699 */ { MAD_F(0x0496526f) /* 0.286699710 */, 17 }, + /* 2700 */ { MAD_F(0x0496e6f5) /* 0.286841351 */, 17 }, + /* 2701 */ { MAD_F(0x04977b7f) /* 0.286983010 */, 17 }, + /* 2702 */ { MAD_F(0x0498100e) /* 0.287124686 */, 17 }, + /* 2703 */ { MAD_F(0x0498a4a1) /* 0.287266380 */, 17 }, + + /* 2704 */ { MAD_F(0x0499393a) /* 0.287408091 */, 17 }, + /* 2705 */ { MAD_F(0x0499cdd7) /* 0.287549820 */, 17 }, + /* 2706 */ { MAD_F(0x049a6278) /* 0.287691566 */, 17 }, + /* 2707 */ { MAD_F(0x049af71f) /* 0.287833330 */, 17 }, + /* 2708 */ { MAD_F(0x049b8bca) /* 0.287975111 */, 17 }, + /* 2709 */ { MAD_F(0x049c207a) /* 0.288116909 */, 17 }, + /* 2710 */ { MAD_F(0x049cb52e) /* 0.288258725 */, 17 }, + /* 2711 */ { MAD_F(0x049d49e7) /* 0.288400559 */, 17 }, + /* 2712 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 17 }, + /* 2713 */ { MAD_F(0x049e7367) /* 0.288684278 */, 17 }, + /* 2714 */ { MAD_F(0x049f082f) /* 0.288826163 */, 17 }, + /* 2715 */ { MAD_F(0x049f9cfa) /* 0.288968067 */, 17 }, + /* 2716 */ { MAD_F(0x04a031cb) /* 0.289109987 */, 17 }, + /* 2717 */ { MAD_F(0x04a0c6a0) /* 0.289251925 */, 17 }, + /* 2718 */ { MAD_F(0x04a15b7a) /* 0.289393881 */, 17 }, + /* 2719 */ { MAD_F(0x04a1f059) /* 0.289535854 */, 17 }, + + /* 2720 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 17 }, + /* 2721 */ { MAD_F(0x04a31a24) /* 0.289819851 */, 17 }, + /* 2722 */ { MAD_F(0x04a3af10) /* 0.289961876 */, 17 }, + /* 2723 */ { MAD_F(0x04a44401) /* 0.290103919 */, 17 }, + /* 2724 */ { MAD_F(0x04a4d8f7) /* 0.290245979 */, 17 }, + /* 2725 */ { MAD_F(0x04a56df2) /* 0.290388056 */, 17 }, + /* 2726 */ { MAD_F(0x04a602f1) /* 0.290530150 */, 17 }, + /* 2727 */ { MAD_F(0x04a697f5) /* 0.290672262 */, 17 }, + /* 2728 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 17 }, + /* 2729 */ { MAD_F(0x04a7c20b) /* 0.290956538 */, 17 }, + /* 2730 */ { MAD_F(0x04a8571d) /* 0.291098703 */, 17 }, + /* 2731 */ { MAD_F(0x04a8ec33) /* 0.291240884 */, 17 }, + /* 2732 */ { MAD_F(0x04a9814e) /* 0.291383083 */, 17 }, + /* 2733 */ { MAD_F(0x04aa166e) /* 0.291525299 */, 17 }, + /* 2734 */ { MAD_F(0x04aaab93) /* 0.291667532 */, 17 }, + /* 2735 */ { MAD_F(0x04ab40bc) /* 0.291809783 */, 17 }, + + /* 2736 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 17 }, + /* 2737 */ { MAD_F(0x04ac6b1c) /* 0.292094337 */, 17 }, + /* 2738 */ { MAD_F(0x04ad0053) /* 0.292236640 */, 17 }, + /* 2739 */ { MAD_F(0x04ad958f) /* 0.292378960 */, 17 }, + /* 2740 */ { MAD_F(0x04ae2ad0) /* 0.292521297 */, 17 }, + /* 2741 */ { MAD_F(0x04aec015) /* 0.292663652 */, 17 }, + /* 2742 */ { MAD_F(0x04af555e) /* 0.292806024 */, 17 }, + /* 2743 */ { MAD_F(0x04afeaad) /* 0.292948414 */, 17 }, + /* 2744 */ { MAD_F(0x04b08000) /* 0.293090820 */, 17 }, + /* 2745 */ { MAD_F(0x04b11557) /* 0.293233244 */, 17 }, + /* 2746 */ { MAD_F(0x04b1aab4) /* 0.293375686 */, 17 }, + /* 2747 */ { MAD_F(0x04b24015) /* 0.293518144 */, 17 }, + /* 2748 */ { MAD_F(0x04b2d57a) /* 0.293660620 */, 17 }, + /* 2749 */ { MAD_F(0x04b36ae4) /* 0.293803113 */, 17 }, + /* 2750 */ { MAD_F(0x04b40053) /* 0.293945624 */, 17 }, + /* 2751 */ { MAD_F(0x04b495c7) /* 0.294088151 */, 17 }, + + /* 2752 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 17 }, + /* 2753 */ { MAD_F(0x04b5c0bc) /* 0.294373259 */, 17 }, + /* 2754 */ { MAD_F(0x04b6563d) /* 0.294515838 */, 17 }, + /* 2755 */ { MAD_F(0x04b6ebc3) /* 0.294658435 */, 17 }, + /* 2756 */ { MAD_F(0x04b7814e) /* 0.294801049 */, 17 }, + /* 2757 */ { MAD_F(0x04b816dd) /* 0.294943680 */, 17 }, + /* 2758 */ { MAD_F(0x04b8ac71) /* 0.295086329 */, 17 }, + /* 2759 */ { MAD_F(0x04b9420a) /* 0.295228995 */, 17 }, + /* 2760 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 17 }, + /* 2761 */ { MAD_F(0x04ba6d49) /* 0.295514378 */, 17 }, + /* 2762 */ { MAD_F(0x04bb02ef) /* 0.295657095 */, 17 }, + /* 2763 */ { MAD_F(0x04bb989a) /* 0.295799830 */, 17 }, + /* 2764 */ { MAD_F(0x04bc2e4a) /* 0.295942582 */, 17 }, + /* 2765 */ { MAD_F(0x04bcc3fe) /* 0.296085351 */, 17 }, + /* 2766 */ { MAD_F(0x04bd59b7) /* 0.296228138 */, 17 }, + /* 2767 */ { MAD_F(0x04bdef74) /* 0.296370941 */, 17 }, + + /* 2768 */ { MAD_F(0x04be8537) /* 0.296513762 */, 17 }, + /* 2769 */ { MAD_F(0x04bf1afd) /* 0.296656600 */, 17 }, + /* 2770 */ { MAD_F(0x04bfb0c9) /* 0.296799455 */, 17 }, + /* 2771 */ { MAD_F(0x04c04699) /* 0.296942327 */, 17 }, + /* 2772 */ { MAD_F(0x04c0dc6d) /* 0.297085217 */, 17 }, + /* 2773 */ { MAD_F(0x04c17247) /* 0.297228124 */, 17 }, + /* 2774 */ { MAD_F(0x04c20824) /* 0.297371048 */, 17 }, + /* 2775 */ { MAD_F(0x04c29e07) /* 0.297513989 */, 17 }, + /* 2776 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 17 }, + /* 2777 */ { MAD_F(0x04c3c9da) /* 0.297799922 */, 17 }, + /* 2778 */ { MAD_F(0x04c45fca) /* 0.297942915 */, 17 }, + /* 2779 */ { MAD_F(0x04c4f5bf) /* 0.298085925 */, 17 }, + /* 2780 */ { MAD_F(0x04c58bb8) /* 0.298228951 */, 17 }, + /* 2781 */ { MAD_F(0x04c621b6) /* 0.298371996 */, 17 }, + /* 2782 */ { MAD_F(0x04c6b7b9) /* 0.298515057 */, 17 }, + /* 2783 */ { MAD_F(0x04c74dc0) /* 0.298658135 */, 17 }, + + /* 2784 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 17 }, + /* 2785 */ { MAD_F(0x04c879dd) /* 0.298944343 */, 17 }, + /* 2786 */ { MAD_F(0x04c90ff2) /* 0.299087473 */, 17 }, + /* 2787 */ { MAD_F(0x04c9a60c) /* 0.299230620 */, 17 }, + /* 2788 */ { MAD_F(0x04ca3c2a) /* 0.299373784 */, 17 }, + /* 2789 */ { MAD_F(0x04cad24d) /* 0.299516965 */, 17 }, + /* 2790 */ { MAD_F(0x04cb6874) /* 0.299660163 */, 17 }, + /* 2791 */ { MAD_F(0x04cbfea0) /* 0.299803378 */, 17 }, + /* 2792 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 17 }, + /* 2793 */ { MAD_F(0x04cd2b06) /* 0.300089860 */, 17 }, + /* 2794 */ { MAD_F(0x04cdc140) /* 0.300233127 */, 17 }, + /* 2795 */ { MAD_F(0x04ce577f) /* 0.300376411 */, 17 }, + /* 2796 */ { MAD_F(0x04ceedc2) /* 0.300519711 */, 17 }, + /* 2797 */ { MAD_F(0x04cf8409) /* 0.300663029 */, 17 }, + /* 2798 */ { MAD_F(0x04d01a55) /* 0.300806364 */, 17 }, + /* 2799 */ { MAD_F(0x04d0b0a6) /* 0.300949716 */, 17 }, + + /* 2800 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 17 }, + /* 2801 */ { MAD_F(0x04d1dd55) /* 0.301236472 */, 17 }, + /* 2802 */ { MAD_F(0x04d273b4) /* 0.301379875 */, 17 }, + /* 2803 */ { MAD_F(0x04d30a17) /* 0.301523295 */, 17 }, + /* 2804 */ { MAD_F(0x04d3a07f) /* 0.301666733 */, 17 }, + /* 2805 */ { MAD_F(0x04d436eb) /* 0.301810187 */, 17 }, + /* 2806 */ { MAD_F(0x04d4cd5c) /* 0.301953659 */, 17 }, + /* 2807 */ { MAD_F(0x04d563d1) /* 0.302097147 */, 17 }, + /* 2808 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 17 }, + /* 2809 */ { MAD_F(0x04d690ca) /* 0.302384175 */, 17 }, + /* 2810 */ { MAD_F(0x04d7274d) /* 0.302527715 */, 17 }, + /* 2811 */ { MAD_F(0x04d7bdd5) /* 0.302671271 */, 17 }, + /* 2812 */ { MAD_F(0x04d85461) /* 0.302814845 */, 17 }, + /* 2813 */ { MAD_F(0x04d8eaf2) /* 0.302958436 */, 17 }, + /* 2814 */ { MAD_F(0x04d98187) /* 0.303102044 */, 17 }, + /* 2815 */ { MAD_F(0x04da1821) /* 0.303245668 */, 17 }, + + /* 2816 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 17 }, + /* 2817 */ { MAD_F(0x04db4563) /* 0.303532969 */, 17 }, + /* 2818 */ { MAD_F(0x04dbdc0a) /* 0.303676645 */, 17 }, + /* 2819 */ { MAD_F(0x04dc72b7) /* 0.303820337 */, 17 }, + /* 2820 */ { MAD_F(0x04dd0967) /* 0.303964047 */, 17 }, + /* 2821 */ { MAD_F(0x04dda01d) /* 0.304107774 */, 17 }, + /* 2822 */ { MAD_F(0x04de36d7) /* 0.304251517 */, 17 }, + /* 2823 */ { MAD_F(0x04decd95) /* 0.304395278 */, 17 }, + /* 2824 */ { MAD_F(0x04df6458) /* 0.304539056 */, 17 }, + /* 2825 */ { MAD_F(0x04dffb20) /* 0.304682850 */, 17 }, + /* 2826 */ { MAD_F(0x04e091ec) /* 0.304826662 */, 17 }, + /* 2827 */ { MAD_F(0x04e128bc) /* 0.304970491 */, 17 }, + /* 2828 */ { MAD_F(0x04e1bf92) /* 0.305114336 */, 17 }, + /* 2829 */ { MAD_F(0x04e2566b) /* 0.305258199 */, 17 }, + /* 2830 */ { MAD_F(0x04e2ed4a) /* 0.305402078 */, 17 }, + /* 2831 */ { MAD_F(0x04e3842d) /* 0.305545974 */, 17 }, + + /* 2832 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 17 }, + /* 2833 */ { MAD_F(0x04e4b200) /* 0.305833818 */, 17 }, + /* 2834 */ { MAD_F(0x04e548f1) /* 0.305977765 */, 17 }, + /* 2835 */ { MAD_F(0x04e5dfe6) /* 0.306121729 */, 17 }, + /* 2836 */ { MAD_F(0x04e676df) /* 0.306265710 */, 17 }, + /* 2837 */ { MAD_F(0x04e70dde) /* 0.306409708 */, 17 }, + /* 2838 */ { MAD_F(0x04e7a4e0) /* 0.306553723 */, 17 }, + /* 2839 */ { MAD_F(0x04e83be7) /* 0.306697755 */, 17 }, + /* 2840 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 17 }, + /* 2841 */ { MAD_F(0x04e96a04) /* 0.306985869 */, 17 }, + /* 2842 */ { MAD_F(0x04ea0118) /* 0.307129952 */, 17 }, + /* 2843 */ { MAD_F(0x04ea9832) /* 0.307274051 */, 17 }, + /* 2844 */ { MAD_F(0x04eb2f50) /* 0.307418168 */, 17 }, + /* 2845 */ { MAD_F(0x04ebc672) /* 0.307562301 */, 17 }, + /* 2846 */ { MAD_F(0x04ec5d99) /* 0.307706451 */, 17 }, + /* 2847 */ { MAD_F(0x04ecf4c5) /* 0.307850618 */, 17 }, + + /* 2848 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 17 }, + /* 2849 */ { MAD_F(0x04ee2329) /* 0.308139003 */, 17 }, + /* 2850 */ { MAD_F(0x04eeba63) /* 0.308283220 */, 17 }, + /* 2851 */ { MAD_F(0x04ef51a0) /* 0.308427455 */, 17 }, + /* 2852 */ { MAD_F(0x04efe8e2) /* 0.308571706 */, 17 }, + /* 2853 */ { MAD_F(0x04f08029) /* 0.308715974 */, 17 }, + /* 2854 */ { MAD_F(0x04f11774) /* 0.308860260 */, 17 }, + /* 2855 */ { MAD_F(0x04f1aec4) /* 0.309004561 */, 17 }, + /* 2856 */ { MAD_F(0x04f24618) /* 0.309148880 */, 17 }, + /* 2857 */ { MAD_F(0x04f2dd71) /* 0.309293216 */, 17 }, + /* 2858 */ { MAD_F(0x04f374cf) /* 0.309437568 */, 17 }, + /* 2859 */ { MAD_F(0x04f40c30) /* 0.309581938 */, 17 }, + /* 2860 */ { MAD_F(0x04f4a397) /* 0.309726324 */, 17 }, + /* 2861 */ { MAD_F(0x04f53b02) /* 0.309870727 */, 17 }, + /* 2862 */ { MAD_F(0x04f5d271) /* 0.310015147 */, 17 }, + /* 2863 */ { MAD_F(0x04f669e5) /* 0.310159583 */, 17 }, + + /* 2864 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 17 }, + /* 2865 */ { MAD_F(0x04f798da) /* 0.310448507 */, 17 }, + /* 2866 */ { MAD_F(0x04f8305c) /* 0.310592994 */, 17 }, + /* 2867 */ { MAD_F(0x04f8c7e2) /* 0.310737498 */, 17 }, + /* 2868 */ { MAD_F(0x04f95f6c) /* 0.310882018 */, 17 }, + /* 2869 */ { MAD_F(0x04f9f6fb) /* 0.311026556 */, 17 }, + /* 2870 */ { MAD_F(0x04fa8e8f) /* 0.311171110 */, 17 }, + /* 2871 */ { MAD_F(0x04fb2627) /* 0.311315681 */, 17 }, + /* 2872 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 17 }, + /* 2873 */ { MAD_F(0x04fc5564) /* 0.311604874 */, 17 }, + /* 2874 */ { MAD_F(0x04fced0a) /* 0.311749495 */, 17 }, + /* 2875 */ { MAD_F(0x04fd84b4) /* 0.311894133 */, 17 }, + /* 2876 */ { MAD_F(0x04fe1c62) /* 0.312038788 */, 17 }, + /* 2877 */ { MAD_F(0x04feb415) /* 0.312183460 */, 17 }, + /* 2878 */ { MAD_F(0x04ff4bcd) /* 0.312328148 */, 17 }, + /* 2879 */ { MAD_F(0x04ffe389) /* 0.312472854 */, 17 }, + + /* 2880 */ { MAD_F(0x05007b49) /* 0.312617576 */, 17 }, + /* 2881 */ { MAD_F(0x0501130e) /* 0.312762314 */, 17 }, + /* 2882 */ { MAD_F(0x0501aad8) /* 0.312907070 */, 17 }, + /* 2883 */ { MAD_F(0x050242a6) /* 0.313051842 */, 17 }, + /* 2884 */ { MAD_F(0x0502da78) /* 0.313196631 */, 17 }, + /* 2885 */ { MAD_F(0x0503724f) /* 0.313341437 */, 17 }, + /* 2886 */ { MAD_F(0x05040a2b) /* 0.313486259 */, 17 }, + /* 2887 */ { MAD_F(0x0504a20b) /* 0.313631098 */, 17 }, + /* 2888 */ { MAD_F(0x050539ef) /* 0.313775954 */, 17 }, + /* 2889 */ { MAD_F(0x0505d1d8) /* 0.313920827 */, 17 }, + /* 2890 */ { MAD_F(0x050669c5) /* 0.314065716 */, 17 }, + /* 2891 */ { MAD_F(0x050701b7) /* 0.314210622 */, 17 }, + /* 2892 */ { MAD_F(0x050799ae) /* 0.314355545 */, 17 }, + /* 2893 */ { MAD_F(0x050831a9) /* 0.314500484 */, 17 }, + /* 2894 */ { MAD_F(0x0508c9a8) /* 0.314645440 */, 17 }, + /* 2895 */ { MAD_F(0x050961ac) /* 0.314790413 */, 17 }, + + /* 2896 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 17 }, + /* 2897 */ { MAD_F(0x050a91c1) /* 0.315080409 */, 17 }, + /* 2898 */ { MAD_F(0x050b29d2) /* 0.315225432 */, 17 }, + /* 2899 */ { MAD_F(0x050bc1e8) /* 0.315370472 */, 17 }, + /* 2900 */ { MAD_F(0x050c5a02) /* 0.315515528 */, 17 }, + /* 2901 */ { MAD_F(0x050cf221) /* 0.315660601 */, 17 }, + /* 2902 */ { MAD_F(0x050d8a44) /* 0.315805690 */, 17 }, + /* 2903 */ { MAD_F(0x050e226c) /* 0.315950797 */, 17 }, + /* 2904 */ { MAD_F(0x050eba98) /* 0.316095920 */, 17 }, + /* 2905 */ { MAD_F(0x050f52c9) /* 0.316241059 */, 17 }, + /* 2906 */ { MAD_F(0x050feafe) /* 0.316386216 */, 17 }, + /* 2907 */ { MAD_F(0x05108337) /* 0.316531388 */, 17 }, + /* 2908 */ { MAD_F(0x05111b75) /* 0.316676578 */, 17 }, + /* 2909 */ { MAD_F(0x0511b3b8) /* 0.316821784 */, 17 }, + /* 2910 */ { MAD_F(0x05124bff) /* 0.316967007 */, 17 }, + /* 2911 */ { MAD_F(0x0512e44a) /* 0.317112247 */, 17 }, + + /* 2912 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 17 }, + /* 2913 */ { MAD_F(0x051414ee) /* 0.317402775 */, 17 }, + /* 2914 */ { MAD_F(0x0514ad47) /* 0.317548065 */, 17 }, + /* 2915 */ { MAD_F(0x051545a5) /* 0.317693371 */, 17 }, + /* 2916 */ { MAD_F(0x0515de06) /* 0.317838693 */, 17 }, + /* 2917 */ { MAD_F(0x0516766d) /* 0.317984033 */, 17 }, + /* 2918 */ { MAD_F(0x05170ed7) /* 0.318129388 */, 17 }, + /* 2919 */ { MAD_F(0x0517a746) /* 0.318274761 */, 17 }, + /* 2920 */ { MAD_F(0x05183fba) /* 0.318420150 */, 17 }, + /* 2921 */ { MAD_F(0x0518d832) /* 0.318565555 */, 17 }, + /* 2922 */ { MAD_F(0x051970ae) /* 0.318710978 */, 17 }, + /* 2923 */ { MAD_F(0x051a092f) /* 0.318856416 */, 17 }, + /* 2924 */ { MAD_F(0x051aa1b5) /* 0.319001872 */, 17 }, + /* 2925 */ { MAD_F(0x051b3a3f) /* 0.319147344 */, 17 }, + /* 2926 */ { MAD_F(0x051bd2cd) /* 0.319292832 */, 17 }, + /* 2927 */ { MAD_F(0x051c6b60) /* 0.319438338 */, 17 }, + + /* 2928 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 17 }, + /* 2929 */ { MAD_F(0x051d9c92) /* 0.319729398 */, 17 }, + /* 2930 */ { MAD_F(0x051e3532) /* 0.319874952 */, 17 }, + /* 2931 */ { MAD_F(0x051ecdd7) /* 0.320020524 */, 17 }, + /* 2932 */ { MAD_F(0x051f6680) /* 0.320166112 */, 17 }, + /* 2933 */ { MAD_F(0x051fff2d) /* 0.320311716 */, 17 }, + /* 2934 */ { MAD_F(0x052097df) /* 0.320457337 */, 17 }, + /* 2935 */ { MAD_F(0x05213095) /* 0.320602975 */, 17 }, + /* 2936 */ { MAD_F(0x0521c950) /* 0.320748629 */, 17 }, + /* 2937 */ { MAD_F(0x0522620f) /* 0.320894300 */, 17 }, + /* 2938 */ { MAD_F(0x0522fad3) /* 0.321039987 */, 17 }, + /* 2939 */ { MAD_F(0x0523939b) /* 0.321185691 */, 17 }, + /* 2940 */ { MAD_F(0x05242c68) /* 0.321331411 */, 17 }, + /* 2941 */ { MAD_F(0x0524c538) /* 0.321477148 */, 17 }, + /* 2942 */ { MAD_F(0x05255e0e) /* 0.321622901 */, 17 }, + /* 2943 */ { MAD_F(0x0525f6e8) /* 0.321768671 */, 17 }, + + /* 2944 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 17 }, + /* 2945 */ { MAD_F(0x052728a9) /* 0.322060260 */, 17 }, + /* 2946 */ { MAD_F(0x0527c190) /* 0.322206079 */, 17 }, + /* 2947 */ { MAD_F(0x05285a7b) /* 0.322351915 */, 17 }, + /* 2948 */ { MAD_F(0x0528f36b) /* 0.322497768 */, 17 }, + /* 2949 */ { MAD_F(0x05298c5f) /* 0.322643636 */, 17 }, + /* 2950 */ { MAD_F(0x052a2558) /* 0.322789522 */, 17 }, + /* 2951 */ { MAD_F(0x052abe55) /* 0.322935424 */, 17 }, + /* 2952 */ { MAD_F(0x052b5757) /* 0.323081342 */, 17 }, + /* 2953 */ { MAD_F(0x052bf05d) /* 0.323227277 */, 17 }, + /* 2954 */ { MAD_F(0x052c8968) /* 0.323373228 */, 17 }, + /* 2955 */ { MAD_F(0x052d2277) /* 0.323519196 */, 17 }, + /* 2956 */ { MAD_F(0x052dbb8a) /* 0.323665180 */, 17 }, + /* 2957 */ { MAD_F(0x052e54a2) /* 0.323811180 */, 17 }, + /* 2958 */ { MAD_F(0x052eedbe) /* 0.323957197 */, 17 }, + /* 2959 */ { MAD_F(0x052f86de) /* 0.324103231 */, 17 }, + + /* 2960 */ { MAD_F(0x05302003) /* 0.324249281 */, 17 }, + /* 2961 */ { MAD_F(0x0530b92d) /* 0.324395347 */, 17 }, + /* 2962 */ { MAD_F(0x0531525b) /* 0.324541430 */, 17 }, + /* 2963 */ { MAD_F(0x0531eb8d) /* 0.324687530 */, 17 }, + /* 2964 */ { MAD_F(0x053284c4) /* 0.324833646 */, 17 }, + /* 2965 */ { MAD_F(0x05331dff) /* 0.324979778 */, 17 }, + /* 2966 */ { MAD_F(0x0533b73e) /* 0.325125926 */, 17 }, + /* 2967 */ { MAD_F(0x05345082) /* 0.325272091 */, 17 }, + /* 2968 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 17 }, + /* 2969 */ { MAD_F(0x05358317) /* 0.325564471 */, 17 }, + /* 2970 */ { MAD_F(0x05361c68) /* 0.325710685 */, 17 }, + /* 2971 */ { MAD_F(0x0536b5be) /* 0.325856916 */, 17 }, + /* 2972 */ { MAD_F(0x05374f17) /* 0.326003163 */, 17 }, + /* 2973 */ { MAD_F(0x0537e876) /* 0.326149427 */, 17 }, + /* 2974 */ { MAD_F(0x053881d9) /* 0.326295707 */, 17 }, + /* 2975 */ { MAD_F(0x05391b40) /* 0.326442003 */, 17 }, + + /* 2976 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 17 }, + /* 2977 */ { MAD_F(0x053a4e1b) /* 0.326734645 */, 17 }, + /* 2978 */ { MAD_F(0x053ae78f) /* 0.326880990 */, 17 }, + /* 2979 */ { MAD_F(0x053b8108) /* 0.327027352 */, 17 }, + /* 2980 */ { MAD_F(0x053c1a85) /* 0.327173730 */, 17 }, + /* 2981 */ { MAD_F(0x053cb407) /* 0.327320125 */, 17 }, + /* 2982 */ { MAD_F(0x053d4d8d) /* 0.327466536 */, 17 }, + /* 2983 */ { MAD_F(0x053de717) /* 0.327612963 */, 17 }, + /* 2984 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 17 }, + /* 2985 */ { MAD_F(0x053f1a39) /* 0.327905867 */, 17 }, + /* 2986 */ { MAD_F(0x053fb3d0) /* 0.328052344 */, 17 }, + /* 2987 */ { MAD_F(0x05404d6c) /* 0.328198837 */, 17 }, + /* 2988 */ { MAD_F(0x0540e70c) /* 0.328345346 */, 17 }, + /* 2989 */ { MAD_F(0x054180b1) /* 0.328491871 */, 17 }, + /* 2990 */ { MAD_F(0x05421a5a) /* 0.328638413 */, 17 }, + /* 2991 */ { MAD_F(0x0542b407) /* 0.328784971 */, 17 }, + + /* 2992 */ { MAD_F(0x05434db9) /* 0.328931546 */, 17 }, + /* 2993 */ { MAD_F(0x0543e76f) /* 0.329078137 */, 17 }, + /* 2994 */ { MAD_F(0x0544812a) /* 0.329224744 */, 17 }, + /* 2995 */ { MAD_F(0x05451ae9) /* 0.329371367 */, 17 }, + /* 2996 */ { MAD_F(0x0545b4ac) /* 0.329518007 */, 17 }, + /* 2997 */ { MAD_F(0x05464e74) /* 0.329664663 */, 17 }, + /* 2998 */ { MAD_F(0x0546e840) /* 0.329811336 */, 17 }, + /* 2999 */ { MAD_F(0x05478211) /* 0.329958024 */, 17 }, + /* 3000 */ { MAD_F(0x05481be5) /* 0.330104730 */, 17 }, + /* 3001 */ { MAD_F(0x0548b5bf) /* 0.330251451 */, 17 }, + /* 3002 */ { MAD_F(0x05494f9c) /* 0.330398189 */, 17 }, + /* 3003 */ { MAD_F(0x0549e97e) /* 0.330544943 */, 17 }, + /* 3004 */ { MAD_F(0x054a8364) /* 0.330691713 */, 17 }, + /* 3005 */ { MAD_F(0x054b1d4f) /* 0.330838499 */, 17 }, + /* 3006 */ { MAD_F(0x054bb73e) /* 0.330985302 */, 17 }, + /* 3007 */ { MAD_F(0x054c5132) /* 0.331132121 */, 17 }, + + /* 3008 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 17 }, + /* 3009 */ { MAD_F(0x054d8526) /* 0.331425808 */, 17 }, + /* 3010 */ { MAD_F(0x054e1f26) /* 0.331572676 */, 17 }, + /* 3011 */ { MAD_F(0x054eb92b) /* 0.331719560 */, 17 }, + /* 3012 */ { MAD_F(0x054f5334) /* 0.331866461 */, 17 }, + /* 3013 */ { MAD_F(0x054fed42) /* 0.332013377 */, 17 }, + /* 3014 */ { MAD_F(0x05508754) /* 0.332160310 */, 17 }, + /* 3015 */ { MAD_F(0x0551216b) /* 0.332307260 */, 17 }, + /* 3016 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 17 }, + /* 3017 */ { MAD_F(0x055255a4) /* 0.332601207 */, 17 }, + /* 3018 */ { MAD_F(0x0552efc8) /* 0.332748205 */, 17 }, + /* 3019 */ { MAD_F(0x055389f0) /* 0.332895219 */, 17 }, + /* 3020 */ { MAD_F(0x0554241c) /* 0.333042249 */, 17 }, + /* 3021 */ { MAD_F(0x0554be4c) /* 0.333189296 */, 17 }, + /* 3022 */ { MAD_F(0x05555881) /* 0.333336359 */, 17 }, + /* 3023 */ { MAD_F(0x0555f2ba) /* 0.333483438 */, 17 }, + + /* 3024 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 17 }, + /* 3025 */ { MAD_F(0x0557273a) /* 0.333777645 */, 17 }, + /* 3026 */ { MAD_F(0x0557c180) /* 0.333924772 */, 17 }, + /* 3027 */ { MAD_F(0x05585bcb) /* 0.334071916 */, 17 }, + /* 3028 */ { MAD_F(0x0558f61a) /* 0.334219076 */, 17 }, + /* 3029 */ { MAD_F(0x0559906d) /* 0.334366253 */, 17 }, + /* 3030 */ { MAD_F(0x055a2ac5) /* 0.334513445 */, 17 }, + /* 3031 */ { MAD_F(0x055ac521) /* 0.334660654 */, 17 }, + /* 3032 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 17 }, + /* 3033 */ { MAD_F(0x055bf9e6) /* 0.334955120 */, 17 }, + /* 3034 */ { MAD_F(0x055c944f) /* 0.335102377 */, 17 }, + /* 3035 */ { MAD_F(0x055d2ebd) /* 0.335249651 */, 17 }, + /* 3036 */ { MAD_F(0x055dc92e) /* 0.335396941 */, 17 }, + /* 3037 */ { MAD_F(0x055e63a5) /* 0.335544246 */, 17 }, + /* 3038 */ { MAD_F(0x055efe1f) /* 0.335691568 */, 17 }, + /* 3039 */ { MAD_F(0x055f989e) /* 0.335838906 */, 17 }, + + /* 3040 */ { MAD_F(0x05603321) /* 0.335986261 */, 17 }, + /* 3041 */ { MAD_F(0x0560cda8) /* 0.336133631 */, 17 }, + /* 3042 */ { MAD_F(0x05616834) /* 0.336281018 */, 17 }, + /* 3043 */ { MAD_F(0x056202c4) /* 0.336428421 */, 17 }, + /* 3044 */ { MAD_F(0x05629d59) /* 0.336575840 */, 17 }, + /* 3045 */ { MAD_F(0x056337f2) /* 0.336723275 */, 17 }, + /* 3046 */ { MAD_F(0x0563d28f) /* 0.336870726 */, 17 }, + /* 3047 */ { MAD_F(0x05646d30) /* 0.337018193 */, 17 }, + /* 3048 */ { MAD_F(0x056507d6) /* 0.337165677 */, 17 }, + /* 3049 */ { MAD_F(0x0565a280) /* 0.337313176 */, 17 }, + /* 3050 */ { MAD_F(0x05663d2f) /* 0.337460692 */, 17 }, + /* 3051 */ { MAD_F(0x0566d7e1) /* 0.337608224 */, 17 }, + /* 3052 */ { MAD_F(0x05677298) /* 0.337755772 */, 17 }, + /* 3053 */ { MAD_F(0x05680d54) /* 0.337903336 */, 17 }, + /* 3054 */ { MAD_F(0x0568a814) /* 0.338050916 */, 17 }, + /* 3055 */ { MAD_F(0x056942d8) /* 0.338198513 */, 17 }, + + /* 3056 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 17 }, + /* 3057 */ { MAD_F(0x056a786d) /* 0.338493753 */, 17 }, + /* 3058 */ { MAD_F(0x056b133e) /* 0.338641398 */, 17 }, + /* 3059 */ { MAD_F(0x056bae13) /* 0.338789059 */, 17 }, + /* 3060 */ { MAD_F(0x056c48ed) /* 0.338936736 */, 17 }, + /* 3061 */ { MAD_F(0x056ce3cb) /* 0.339084429 */, 17 }, + /* 3062 */ { MAD_F(0x056d7ead) /* 0.339232138 */, 17 }, + /* 3063 */ { MAD_F(0x056e1994) /* 0.339379863 */, 17 }, + /* 3064 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 17 }, + /* 3065 */ { MAD_F(0x056f4f6e) /* 0.339675361 */, 17 }, + /* 3066 */ { MAD_F(0x056fea62) /* 0.339823134 */, 17 }, + /* 3067 */ { MAD_F(0x0570855a) /* 0.339970924 */, 17 }, + /* 3068 */ { MAD_F(0x05712056) /* 0.340118729 */, 17 }, + /* 3069 */ { MAD_F(0x0571bb56) /* 0.340266550 */, 17 }, + /* 3070 */ { MAD_F(0x0572565b) /* 0.340414388 */, 17 }, + /* 3071 */ { MAD_F(0x0572f164) /* 0.340562242 */, 17 }, + + /* 3072 */ { MAD_F(0x05738c72) /* 0.340710111 */, 17 }, + /* 3073 */ { MAD_F(0x05742784) /* 0.340857997 */, 17 }, + /* 3074 */ { MAD_F(0x0574c29a) /* 0.341005899 */, 17 }, + /* 3075 */ { MAD_F(0x05755db4) /* 0.341153816 */, 17 }, + /* 3076 */ { MAD_F(0x0575f8d3) /* 0.341301750 */, 17 }, + /* 3077 */ { MAD_F(0x057693f6) /* 0.341449700 */, 17 }, + /* 3078 */ { MAD_F(0x05772f1d) /* 0.341597666 */, 17 }, + /* 3079 */ { MAD_F(0x0577ca49) /* 0.341745648 */, 17 }, + /* 3080 */ { MAD_F(0x05786578) /* 0.341893646 */, 17 }, + /* 3081 */ { MAD_F(0x057900ad) /* 0.342041659 */, 17 }, + /* 3082 */ { MAD_F(0x05799be5) /* 0.342189689 */, 17 }, + /* 3083 */ { MAD_F(0x057a3722) /* 0.342337735 */, 17 }, + /* 3084 */ { MAD_F(0x057ad263) /* 0.342485797 */, 17 }, + /* 3085 */ { MAD_F(0x057b6da8) /* 0.342633875 */, 17 }, + /* 3086 */ { MAD_F(0x057c08f2) /* 0.342781969 */, 17 }, + /* 3087 */ { MAD_F(0x057ca440) /* 0.342930079 */, 17 }, + + /* 3088 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 17 }, + /* 3089 */ { MAD_F(0x057ddae9) /* 0.343226347 */, 17 }, + /* 3090 */ { MAD_F(0x057e7644) /* 0.343374505 */, 17 }, + /* 3091 */ { MAD_F(0x057f11a3) /* 0.343522679 */, 17 }, + /* 3092 */ { MAD_F(0x057fad06) /* 0.343670869 */, 17 }, + /* 3093 */ { MAD_F(0x0580486e) /* 0.343819075 */, 17 }, + /* 3094 */ { MAD_F(0x0580e3da) /* 0.343967296 */, 17 }, + /* 3095 */ { MAD_F(0x05817f4a) /* 0.344115534 */, 17 }, + /* 3096 */ { MAD_F(0x05821abf) /* 0.344263788 */, 17 }, + /* 3097 */ { MAD_F(0x0582b638) /* 0.344412058 */, 17 }, + /* 3098 */ { MAD_F(0x058351b5) /* 0.344560343 */, 17 }, + /* 3099 */ { MAD_F(0x0583ed36) /* 0.344708645 */, 17 }, + /* 3100 */ { MAD_F(0x058488bc) /* 0.344856963 */, 17 }, + /* 3101 */ { MAD_F(0x05852446) /* 0.345005296 */, 17 }, + /* 3102 */ { MAD_F(0x0585bfd4) /* 0.345153646 */, 17 }, + /* 3103 */ { MAD_F(0x05865b67) /* 0.345302011 */, 17 }, + + /* 3104 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 17 }, + /* 3105 */ { MAD_F(0x05879298) /* 0.345598790 */, 17 }, + /* 3106 */ { MAD_F(0x05882e38) /* 0.345747203 */, 17 }, + /* 3107 */ { MAD_F(0x0588c9dc) /* 0.345895632 */, 17 }, + /* 3108 */ { MAD_F(0x05896583) /* 0.346044077 */, 17 }, + /* 3109 */ { MAD_F(0x058a0130) /* 0.346192538 */, 17 }, + /* 3110 */ { MAD_F(0x058a9ce0) /* 0.346341015 */, 17 }, + /* 3111 */ { MAD_F(0x058b3895) /* 0.346489508 */, 17 }, + /* 3112 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 17 }, + /* 3113 */ { MAD_F(0x058c700b) /* 0.346786542 */, 17 }, + /* 3114 */ { MAD_F(0x058d0bcd) /* 0.346935082 */, 17 }, + /* 3115 */ { MAD_F(0x058da793) /* 0.347083639 */, 17 }, + /* 3116 */ { MAD_F(0x058e435d) /* 0.347232211 */, 17 }, + /* 3117 */ { MAD_F(0x058edf2b) /* 0.347380799 */, 17 }, + /* 3118 */ { MAD_F(0x058f7afe) /* 0.347529403 */, 17 }, + /* 3119 */ { MAD_F(0x059016d5) /* 0.347678023 */, 17 }, + + /* 3120 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 17 }, + /* 3121 */ { MAD_F(0x05914e8f) /* 0.347975311 */, 17 }, + /* 3122 */ { MAD_F(0x0591ea73) /* 0.348123979 */, 17 }, + /* 3123 */ { MAD_F(0x0592865b) /* 0.348272662 */, 17 }, + /* 3124 */ { MAD_F(0x05932247) /* 0.348421362 */, 17 }, + /* 3125 */ { MAD_F(0x0593be37) /* 0.348570077 */, 17 }, + /* 3126 */ { MAD_F(0x05945a2c) /* 0.348718808 */, 17 }, + /* 3127 */ { MAD_F(0x0594f625) /* 0.348867555 */, 17 }, + /* 3128 */ { MAD_F(0x05959222) /* 0.349016318 */, 17 }, + /* 3129 */ { MAD_F(0x05962e24) /* 0.349165097 */, 17 }, + /* 3130 */ { MAD_F(0x0596ca2a) /* 0.349313892 */, 17 }, + /* 3131 */ { MAD_F(0x05976634) /* 0.349462702 */, 17 }, + /* 3132 */ { MAD_F(0x05980242) /* 0.349611528 */, 17 }, + /* 3133 */ { MAD_F(0x05989e54) /* 0.349760370 */, 17 }, + /* 3134 */ { MAD_F(0x05993a6b) /* 0.349909228 */, 17 }, + /* 3135 */ { MAD_F(0x0599d686) /* 0.350058102 */, 17 }, + + /* 3136 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 17 }, + /* 3137 */ { MAD_F(0x059b0ec9) /* 0.350355897 */, 17 }, + /* 3138 */ { MAD_F(0x059baaf1) /* 0.350504818 */, 17 }, + /* 3139 */ { MAD_F(0x059c471d) /* 0.350653756 */, 17 }, + /* 3140 */ { MAD_F(0x059ce34d) /* 0.350802708 */, 17 }, + /* 3141 */ { MAD_F(0x059d7f81) /* 0.350951677 */, 17 }, + /* 3142 */ { MAD_F(0x059e1bba) /* 0.351100662 */, 17 }, + /* 3143 */ { MAD_F(0x059eb7f7) /* 0.351249662 */, 17 }, + /* 3144 */ { MAD_F(0x059f5438) /* 0.351398678 */, 17 }, + /* 3145 */ { MAD_F(0x059ff07e) /* 0.351547710 */, 17 }, + /* 3146 */ { MAD_F(0x05a08cc7) /* 0.351696758 */, 17 }, + /* 3147 */ { MAD_F(0x05a12915) /* 0.351845821 */, 17 }, + /* 3148 */ { MAD_F(0x05a1c567) /* 0.351994901 */, 17 }, + /* 3149 */ { MAD_F(0x05a261be) /* 0.352143996 */, 17 }, + /* 3150 */ { MAD_F(0x05a2fe18) /* 0.352293107 */, 17 }, + /* 3151 */ { MAD_F(0x05a39a77) /* 0.352442233 */, 17 }, + + /* 3152 */ { MAD_F(0x05a436da) /* 0.352591376 */, 17 }, + /* 3153 */ { MAD_F(0x05a4d342) /* 0.352740534 */, 17 }, + /* 3154 */ { MAD_F(0x05a56fad) /* 0.352889708 */, 17 }, + /* 3155 */ { MAD_F(0x05a60c1d) /* 0.353038898 */, 17 }, + /* 3156 */ { MAD_F(0x05a6a891) /* 0.353188103 */, 17 }, + /* 3157 */ { MAD_F(0x05a7450a) /* 0.353337325 */, 17 }, + /* 3158 */ { MAD_F(0x05a7e186) /* 0.353486562 */, 17 }, + /* 3159 */ { MAD_F(0x05a87e07) /* 0.353635814 */, 17 }, + /* 3160 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 17 }, + /* 3161 */ { MAD_F(0x05a9b715) /* 0.353934367 */, 17 }, + /* 3162 */ { MAD_F(0x05aa53a2) /* 0.354083667 */, 17 }, + /* 3163 */ { MAD_F(0x05aaf034) /* 0.354232983 */, 17 }, + /* 3164 */ { MAD_F(0x05ab8cca) /* 0.354382314 */, 17 }, + /* 3165 */ { MAD_F(0x05ac2964) /* 0.354531662 */, 17 }, + /* 3166 */ { MAD_F(0x05acc602) /* 0.354681025 */, 17 }, + /* 3167 */ { MAD_F(0x05ad62a5) /* 0.354830403 */, 17 }, + + /* 3168 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 17 }, + /* 3169 */ { MAD_F(0x05ae9bf7) /* 0.355129208 */, 17 }, + /* 3170 */ { MAD_F(0x05af38a6) /* 0.355278634 */, 17 }, + /* 3171 */ { MAD_F(0x05afd559) /* 0.355428075 */, 17 }, + /* 3172 */ { MAD_F(0x05b07211) /* 0.355577533 */, 17 }, + /* 3173 */ { MAD_F(0x05b10ecd) /* 0.355727006 */, 17 }, + /* 3174 */ { MAD_F(0x05b1ab8d) /* 0.355876494 */, 17 }, + /* 3175 */ { MAD_F(0x05b24851) /* 0.356025999 */, 17 }, + /* 3176 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 17 }, + /* 3177 */ { MAD_F(0x05b381e6) /* 0.356325054 */, 17 }, + /* 3178 */ { MAD_F(0x05b41eb7) /* 0.356474606 */, 17 }, + /* 3179 */ { MAD_F(0x05b4bb8c) /* 0.356624173 */, 17 }, + /* 3180 */ { MAD_F(0x05b55866) /* 0.356773756 */, 17 }, + /* 3181 */ { MAD_F(0x05b5f543) /* 0.356923354 */, 17 }, + /* 3182 */ { MAD_F(0x05b69225) /* 0.357072969 */, 17 }, + /* 3183 */ { MAD_F(0x05b72f0b) /* 0.357222598 */, 17 }, + + /* 3184 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 17 }, + /* 3185 */ { MAD_F(0x05b868e3) /* 0.357521905 */, 17 }, + /* 3186 */ { MAD_F(0x05b905d6) /* 0.357671582 */, 17 }, + /* 3187 */ { MAD_F(0x05b9a2cd) /* 0.357821275 */, 17 }, + /* 3188 */ { MAD_F(0x05ba3fc8) /* 0.357970983 */, 17 }, + /* 3189 */ { MAD_F(0x05badcc7) /* 0.358120707 */, 17 }, + /* 3190 */ { MAD_F(0x05bb79ca) /* 0.358270446 */, 17 }, + /* 3191 */ { MAD_F(0x05bc16d2) /* 0.358420201 */, 17 }, + /* 3192 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 17 }, + /* 3193 */ { MAD_F(0x05bd50ee) /* 0.358719758 */, 17 }, + /* 3194 */ { MAD_F(0x05bdee02) /* 0.358869560 */, 17 }, + /* 3195 */ { MAD_F(0x05be8b1a) /* 0.359019378 */, 17 }, + /* 3196 */ { MAD_F(0x05bf2837) /* 0.359169211 */, 17 }, + /* 3197 */ { MAD_F(0x05bfc558) /* 0.359319060 */, 17 }, + /* 3198 */ { MAD_F(0x05c0627d) /* 0.359468925 */, 17 }, + /* 3199 */ { MAD_F(0x05c0ffa6) /* 0.359618805 */, 17 }, + + /* 3200 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 17 }, + /* 3201 */ { MAD_F(0x05c23a05) /* 0.359918612 */, 17 }, + /* 3202 */ { MAD_F(0x05c2d73a) /* 0.360068540 */, 17 }, + /* 3203 */ { MAD_F(0x05c37474) /* 0.360218482 */, 17 }, + /* 3204 */ { MAD_F(0x05c411b2) /* 0.360368440 */, 17 }, + /* 3205 */ { MAD_F(0x05c4aef5) /* 0.360518414 */, 17 }, + /* 3206 */ { MAD_F(0x05c54c3b) /* 0.360668404 */, 17 }, + /* 3207 */ { MAD_F(0x05c5e986) /* 0.360818409 */, 17 }, + /* 3208 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 17 }, + /* 3209 */ { MAD_F(0x05c72428) /* 0.361118466 */, 17 }, + /* 3210 */ { MAD_F(0x05c7c17f) /* 0.361268517 */, 17 }, + /* 3211 */ { MAD_F(0x05c85eda) /* 0.361418585 */, 17 }, + /* 3212 */ { MAD_F(0x05c8fc3a) /* 0.361568668 */, 17 }, + /* 3213 */ { MAD_F(0x05c9999e) /* 0.361718766 */, 17 }, + /* 3214 */ { MAD_F(0x05ca3706) /* 0.361868881 */, 17 }, + /* 3215 */ { MAD_F(0x05cad472) /* 0.362019010 */, 17 }, + + /* 3216 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 17 }, + /* 3217 */ { MAD_F(0x05cc0f57) /* 0.362319316 */, 17 }, + /* 3218 */ { MAD_F(0x05ccaccf) /* 0.362469493 */, 17 }, + /* 3219 */ { MAD_F(0x05cd4a4c) /* 0.362619685 */, 17 }, + /* 3220 */ { MAD_F(0x05cde7cd) /* 0.362769892 */, 17 }, + /* 3221 */ { MAD_F(0x05ce8552) /* 0.362920115 */, 17 }, + /* 3222 */ { MAD_F(0x05cf22dc) /* 0.363070354 */, 17 }, + /* 3223 */ { MAD_F(0x05cfc069) /* 0.363220608 */, 17 }, + /* 3224 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 17 }, + /* 3225 */ { MAD_F(0x05d0fb91) /* 0.363521163 */, 17 }, + /* 3226 */ { MAD_F(0x05d1992b) /* 0.363671464 */, 17 }, + /* 3227 */ { MAD_F(0x05d236c9) /* 0.363821780 */, 17 }, + /* 3228 */ { MAD_F(0x05d2d46c) /* 0.363972112 */, 17 }, + /* 3229 */ { MAD_F(0x05d37212) /* 0.364122459 */, 17 }, + /* 3230 */ { MAD_F(0x05d40fbd) /* 0.364272822 */, 17 }, + /* 3231 */ { MAD_F(0x05d4ad6c) /* 0.364423200 */, 17 }, + + /* 3232 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 17 }, + /* 3233 */ { MAD_F(0x05d5e8d6) /* 0.364724004 */, 17 }, + /* 3234 */ { MAD_F(0x05d68691) /* 0.364874429 */, 17 }, + /* 3235 */ { MAD_F(0x05d72451) /* 0.365024869 */, 17 }, + /* 3236 */ { MAD_F(0x05d7c215) /* 0.365175325 */, 17 }, + /* 3237 */ { MAD_F(0x05d85fdc) /* 0.365325796 */, 17 }, + /* 3238 */ { MAD_F(0x05d8fda8) /* 0.365476283 */, 17 }, + /* 3239 */ { MAD_F(0x05d99b79) /* 0.365626786 */, 17 }, + /* 3240 */ { MAD_F(0x05da394d) /* 0.365777304 */, 17 }, + /* 3241 */ { MAD_F(0x05dad726) /* 0.365927837 */, 17 }, + /* 3242 */ { MAD_F(0x05db7502) /* 0.366078386 */, 17 }, + /* 3243 */ { MAD_F(0x05dc12e3) /* 0.366228950 */, 17 }, + /* 3244 */ { MAD_F(0x05dcb0c8) /* 0.366379530 */, 17 }, + /* 3245 */ { MAD_F(0x05dd4eb1) /* 0.366530125 */, 17 }, + /* 3246 */ { MAD_F(0x05ddec9e) /* 0.366680736 */, 17 }, + /* 3247 */ { MAD_F(0x05de8a90) /* 0.366831362 */, 17 }, + + /* 3248 */ { MAD_F(0x05df2885) /* 0.366982004 */, 17 }, + /* 3249 */ { MAD_F(0x05dfc67f) /* 0.367132661 */, 17 }, + /* 3250 */ { MAD_F(0x05e0647d) /* 0.367283334 */, 17 }, + /* 3251 */ { MAD_F(0x05e1027f) /* 0.367434022 */, 17 }, + /* 3252 */ { MAD_F(0x05e1a085) /* 0.367584725 */, 17 }, + /* 3253 */ { MAD_F(0x05e23e8f) /* 0.367735444 */, 17 }, + /* 3254 */ { MAD_F(0x05e2dc9e) /* 0.367886179 */, 17 }, + /* 3255 */ { MAD_F(0x05e37ab0) /* 0.368036929 */, 17 }, + /* 3256 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 17 }, + /* 3257 */ { MAD_F(0x05e4b6e2) /* 0.368338475 */, 17 }, + /* 3258 */ { MAD_F(0x05e55501) /* 0.368489271 */, 17 }, + /* 3259 */ { MAD_F(0x05e5f324) /* 0.368640082 */, 17 }, + /* 3260 */ { MAD_F(0x05e6914c) /* 0.368790909 */, 17 }, + /* 3261 */ { MAD_F(0x05e72f77) /* 0.368941752 */, 17 }, + /* 3262 */ { MAD_F(0x05e7cda7) /* 0.369092610 */, 17 }, + /* 3263 */ { MAD_F(0x05e86bda) /* 0.369243483 */, 17 }, + + /* 3264 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 17 }, + /* 3265 */ { MAD_F(0x05e9a84e) /* 0.369545276 */, 17 }, + /* 3266 */ { MAD_F(0x05ea468e) /* 0.369696195 */, 17 }, + /* 3267 */ { MAD_F(0x05eae4d3) /* 0.369847130 */, 17 }, + /* 3268 */ { MAD_F(0x05eb831b) /* 0.369998080 */, 17 }, + /* 3269 */ { MAD_F(0x05ec2168) /* 0.370149046 */, 17 }, + /* 3270 */ { MAD_F(0x05ecbfb8) /* 0.370300027 */, 17 }, + /* 3271 */ { MAD_F(0x05ed5e0d) /* 0.370451024 */, 17 }, + /* 3272 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 17 }, + /* 3273 */ { MAD_F(0x05ee9ac3) /* 0.370753063 */, 17 }, + /* 3274 */ { MAD_F(0x05ef3924) /* 0.370904105 */, 17 }, + /* 3275 */ { MAD_F(0x05efd78a) /* 0.371055163 */, 17 }, + /* 3276 */ { MAD_F(0x05f075f3) /* 0.371206237 */, 17 }, + /* 3277 */ { MAD_F(0x05f11461) /* 0.371357326 */, 17 }, + /* 3278 */ { MAD_F(0x05f1b2d3) /* 0.371508430 */, 17 }, + /* 3279 */ { MAD_F(0x05f25148) /* 0.371659549 */, 17 }, + + /* 3280 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 17 }, + /* 3281 */ { MAD_F(0x05f38e40) /* 0.371961834 */, 17 }, + /* 3282 */ { MAD_F(0x05f42cc3) /* 0.372113000 */, 17 }, + /* 3283 */ { MAD_F(0x05f4cb49) /* 0.372264181 */, 17 }, + /* 3284 */ { MAD_F(0x05f569d3) /* 0.372415377 */, 17 }, + /* 3285 */ { MAD_F(0x05f60862) /* 0.372566589 */, 17 }, + /* 3286 */ { MAD_F(0x05f6a6f5) /* 0.372717816 */, 17 }, + /* 3287 */ { MAD_F(0x05f7458b) /* 0.372869058 */, 17 }, + /* 3288 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 17 }, + /* 3289 */ { MAD_F(0x05f882c5) /* 0.373171589 */, 17 }, + /* 3290 */ { MAD_F(0x05f92169) /* 0.373322877 */, 17 }, + /* 3291 */ { MAD_F(0x05f9c010) /* 0.373474181 */, 17 }, + /* 3292 */ { MAD_F(0x05fa5ebb) /* 0.373625500 */, 17 }, + /* 3293 */ { MAD_F(0x05fafd6b) /* 0.373776834 */, 17 }, + /* 3294 */ { MAD_F(0x05fb9c1e) /* 0.373928184 */, 17 }, + /* 3295 */ { MAD_F(0x05fc3ad6) /* 0.374079549 */, 17 }, + + /* 3296 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 17 }, + /* 3297 */ { MAD_F(0x05fd7852) /* 0.374382325 */, 17 }, + /* 3298 */ { MAD_F(0x05fe1716) /* 0.374533735 */, 17 }, + /* 3299 */ { MAD_F(0x05feb5de) /* 0.374685162 */, 17 }, + /* 3300 */ { MAD_F(0x05ff54aa) /* 0.374836603 */, 17 }, + /* 3301 */ { MAD_F(0x05fff37b) /* 0.374988060 */, 17 }, + /* 3302 */ { MAD_F(0x0600924f) /* 0.375139532 */, 17 }, + /* 3303 */ { MAD_F(0x06013128) /* 0.375291019 */, 17 }, + /* 3304 */ { MAD_F(0x0601d004) /* 0.375442522 */, 17 }, + /* 3305 */ { MAD_F(0x06026ee5) /* 0.375594040 */, 17 }, + /* 3306 */ { MAD_F(0x06030dca) /* 0.375745573 */, 17 }, + /* 3307 */ { MAD_F(0x0603acb3) /* 0.375897122 */, 17 }, + /* 3308 */ { MAD_F(0x06044ba0) /* 0.376048685 */, 17 }, + /* 3309 */ { MAD_F(0x0604ea91) /* 0.376200265 */, 17 }, + /* 3310 */ { MAD_F(0x06058987) /* 0.376351859 */, 17 }, + /* 3311 */ { MAD_F(0x06062880) /* 0.376503468 */, 17 }, + + /* 3312 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 17 }, + /* 3313 */ { MAD_F(0x0607667f) /* 0.376806733 */, 17 }, + /* 3314 */ { MAD_F(0x06080585) /* 0.376958389 */, 17 }, + /* 3315 */ { MAD_F(0x0608a48f) /* 0.377110059 */, 17 }, + /* 3316 */ { MAD_F(0x0609439c) /* 0.377261745 */, 17 }, + /* 3317 */ { MAD_F(0x0609e2ae) /* 0.377413446 */, 17 }, + /* 3318 */ { MAD_F(0x060a81c4) /* 0.377565163 */, 17 }, + /* 3319 */ { MAD_F(0x060b20df) /* 0.377716894 */, 17 }, + /* 3320 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 17 }, + /* 3321 */ { MAD_F(0x060c5f1f) /* 0.378020403 */, 17 }, + /* 3322 */ { MAD_F(0x060cfe46) /* 0.378172181 */, 17 }, + /* 3323 */ { MAD_F(0x060d9d70) /* 0.378323973 */, 17 }, + /* 3324 */ { MAD_F(0x060e3c9f) /* 0.378475781 */, 17 }, + /* 3325 */ { MAD_F(0x060edbd1) /* 0.378627604 */, 17 }, + /* 3326 */ { MAD_F(0x060f7b08) /* 0.378779442 */, 17 }, + /* 3327 */ { MAD_F(0x06101a43) /* 0.378931296 */, 17 }, + + /* 3328 */ { MAD_F(0x0610b982) /* 0.379083164 */, 17 }, + /* 3329 */ { MAD_F(0x061158c5) /* 0.379235048 */, 17 }, + /* 3330 */ { MAD_F(0x0611f80c) /* 0.379386947 */, 17 }, + /* 3331 */ { MAD_F(0x06129757) /* 0.379538862 */, 17 }, + /* 3332 */ { MAD_F(0x061336a6) /* 0.379690791 */, 17 }, + /* 3333 */ { MAD_F(0x0613d5fa) /* 0.379842736 */, 17 }, + /* 3334 */ { MAD_F(0x06147551) /* 0.379994696 */, 17 }, + /* 3335 */ { MAD_F(0x061514ad) /* 0.380146671 */, 17 }, + /* 3336 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 17 }, + /* 3337 */ { MAD_F(0x06165370) /* 0.380450666 */, 17 }, + /* 3338 */ { MAD_F(0x0616f2d8) /* 0.380602687 */, 17 }, + /* 3339 */ { MAD_F(0x06179243) /* 0.380754723 */, 17 }, + /* 3340 */ { MAD_F(0x061831b3) /* 0.380906774 */, 17 }, + /* 3341 */ { MAD_F(0x0618d127) /* 0.381058840 */, 17 }, + /* 3342 */ { MAD_F(0x0619709f) /* 0.381210921 */, 17 }, + /* 3343 */ { MAD_F(0x061a101b) /* 0.381363018 */, 17 }, + + /* 3344 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 17 }, + /* 3345 */ { MAD_F(0x061b4f20) /* 0.381667257 */, 17 }, + /* 3346 */ { MAD_F(0x061beea8) /* 0.381819399 */, 17 }, + /* 3347 */ { MAD_F(0x061c8e34) /* 0.381971556 */, 17 }, + /* 3348 */ { MAD_F(0x061d2dc5) /* 0.382123728 */, 17 }, + /* 3349 */ { MAD_F(0x061dcd59) /* 0.382275916 */, 17 }, + /* 3350 */ { MAD_F(0x061e6cf2) /* 0.382428118 */, 17 }, + /* 3351 */ { MAD_F(0x061f0c8f) /* 0.382580336 */, 17 }, + /* 3352 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 17 }, + /* 3353 */ { MAD_F(0x06204bd4) /* 0.382884817 */, 17 }, + /* 3354 */ { MAD_F(0x0620eb7d) /* 0.383037080 */, 17 }, + /* 3355 */ { MAD_F(0x06218b2a) /* 0.383189358 */, 17 }, + /* 3356 */ { MAD_F(0x06222adb) /* 0.383341652 */, 17 }, + /* 3357 */ { MAD_F(0x0622ca90) /* 0.383493960 */, 17 }, + /* 3358 */ { MAD_F(0x06236a49) /* 0.383646284 */, 17 }, + /* 3359 */ { MAD_F(0x06240a06) /* 0.383798623 */, 17 }, + + /* 3360 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 17 }, + /* 3361 */ { MAD_F(0x0625498d) /* 0.384103346 */, 17 }, + /* 3362 */ { MAD_F(0x0625e956) /* 0.384255730 */, 17 }, + /* 3363 */ { MAD_F(0x06268923) /* 0.384408129 */, 17 }, + /* 3364 */ { MAD_F(0x062728f5) /* 0.384560544 */, 17 }, + /* 3365 */ { MAD_F(0x0627c8ca) /* 0.384712973 */, 17 }, + /* 3366 */ { MAD_F(0x062868a4) /* 0.384865418 */, 17 }, + /* 3367 */ { MAD_F(0x06290881) /* 0.385017878 */, 17 }, + /* 3368 */ { MAD_F(0x0629a863) /* 0.385170352 */, 17 }, + /* 3369 */ { MAD_F(0x062a4849) /* 0.385322842 */, 17 }, + /* 3370 */ { MAD_F(0x062ae832) /* 0.385475347 */, 17 }, + /* 3371 */ { MAD_F(0x062b8820) /* 0.385627867 */, 17 }, + /* 3372 */ { MAD_F(0x062c2812) /* 0.385780402 */, 17 }, + /* 3373 */ { MAD_F(0x062cc808) /* 0.385932953 */, 17 }, + /* 3374 */ { MAD_F(0x062d6802) /* 0.386085518 */, 17 }, + /* 3375 */ { MAD_F(0x062e0800) /* 0.386238098 */, 17 }, + + /* 3376 */ { MAD_F(0x062ea802) /* 0.386390694 */, 17 }, + /* 3377 */ { MAD_F(0x062f4808) /* 0.386543304 */, 17 }, + /* 3378 */ { MAD_F(0x062fe812) /* 0.386695930 */, 17 }, + /* 3379 */ { MAD_F(0x06308820) /* 0.386848570 */, 17 }, + /* 3380 */ { MAD_F(0x06312832) /* 0.387001226 */, 17 }, + /* 3381 */ { MAD_F(0x0631c849) /* 0.387153897 */, 17 }, + /* 3382 */ { MAD_F(0x06326863) /* 0.387306582 */, 17 }, + /* 3383 */ { MAD_F(0x06330881) /* 0.387459283 */, 17 }, + /* 3384 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 17 }, + /* 3385 */ { MAD_F(0x063448ca) /* 0.387764730 */, 17 }, + /* 3386 */ { MAD_F(0x0634e8f4) /* 0.387917476 */, 17 }, + /* 3387 */ { MAD_F(0x06358923) /* 0.388070237 */, 17 }, + /* 3388 */ { MAD_F(0x06362955) /* 0.388223013 */, 17 }, + /* 3389 */ { MAD_F(0x0636c98c) /* 0.388375804 */, 17 }, + /* 3390 */ { MAD_F(0x063769c6) /* 0.388528610 */, 17 }, + /* 3391 */ { MAD_F(0x06380a05) /* 0.388681431 */, 17 }, + + /* 3392 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 17 }, + /* 3393 */ { MAD_F(0x06394a8e) /* 0.388987119 */, 17 }, + /* 3394 */ { MAD_F(0x0639ead9) /* 0.389139985 */, 17 }, + /* 3395 */ { MAD_F(0x063a8b28) /* 0.389292866 */, 17 }, + /* 3396 */ { MAD_F(0x063b2b7b) /* 0.389445762 */, 17 }, + /* 3397 */ { MAD_F(0x063bcbd1) /* 0.389598674 */, 17 }, + /* 3398 */ { MAD_F(0x063c6c2c) /* 0.389751600 */, 17 }, + /* 3399 */ { MAD_F(0x063d0c8b) /* 0.389904541 */, 17 }, + /* 3400 */ { MAD_F(0x063dacee) /* 0.390057497 */, 17 }, + /* 3401 */ { MAD_F(0x063e4d55) /* 0.390210468 */, 17 }, + /* 3402 */ { MAD_F(0x063eedc0) /* 0.390363455 */, 17 }, + /* 3403 */ { MAD_F(0x063f8e2f) /* 0.390516456 */, 17 }, + /* 3404 */ { MAD_F(0x06402ea2) /* 0.390669472 */, 17 }, + /* 3405 */ { MAD_F(0x0640cf19) /* 0.390822503 */, 17 }, + /* 3406 */ { MAD_F(0x06416f94) /* 0.390975549 */, 17 }, + /* 3407 */ { MAD_F(0x06421013) /* 0.391128611 */, 17 }, + + /* 3408 */ { MAD_F(0x0642b096) /* 0.391281687 */, 17 }, + /* 3409 */ { MAD_F(0x0643511d) /* 0.391434778 */, 17 }, + /* 3410 */ { MAD_F(0x0643f1a8) /* 0.391587884 */, 17 }, + /* 3411 */ { MAD_F(0x06449237) /* 0.391741005 */, 17 }, + /* 3412 */ { MAD_F(0x064532ca) /* 0.391894141 */, 17 }, + /* 3413 */ { MAD_F(0x0645d361) /* 0.392047292 */, 17 }, + /* 3414 */ { MAD_F(0x064673fc) /* 0.392200458 */, 17 }, + /* 3415 */ { MAD_F(0x0647149c) /* 0.392353638 */, 17 }, + /* 3416 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 17 }, + /* 3417 */ { MAD_F(0x064855e6) /* 0.392660045 */, 17 }, + /* 3418 */ { MAD_F(0x0648f691) /* 0.392813271 */, 17 }, + /* 3419 */ { MAD_F(0x06499740) /* 0.392966511 */, 17 }, + /* 3420 */ { MAD_F(0x064a37f4) /* 0.393119767 */, 17 }, + /* 3421 */ { MAD_F(0x064ad8ab) /* 0.393273038 */, 17 }, + /* 3422 */ { MAD_F(0x064b7966) /* 0.393426323 */, 17 }, + /* 3423 */ { MAD_F(0x064c1a25) /* 0.393579623 */, 17 }, + + /* 3424 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 17 }, + /* 3425 */ { MAD_F(0x064d5bb0) /* 0.393886269 */, 17 }, + /* 3426 */ { MAD_F(0x064dfc7b) /* 0.394039614 */, 17 }, + /* 3427 */ { MAD_F(0x064e9d4b) /* 0.394192974 */, 17 }, + /* 3428 */ { MAD_F(0x064f3e1e) /* 0.394346349 */, 17 }, + /* 3429 */ { MAD_F(0x064fdef5) /* 0.394499739 */, 17 }, + /* 3430 */ { MAD_F(0x06507fd0) /* 0.394653144 */, 17 }, + /* 3431 */ { MAD_F(0x065120b0) /* 0.394806564 */, 17 }, + /* 3432 */ { MAD_F(0x0651c193) /* 0.394959999 */, 17 }, + /* 3433 */ { MAD_F(0x0652627a) /* 0.395113448 */, 17 }, + /* 3434 */ { MAD_F(0x06530366) /* 0.395266913 */, 17 }, + /* 3435 */ { MAD_F(0x0653a455) /* 0.395420392 */, 17 }, + /* 3436 */ { MAD_F(0x06544548) /* 0.395573886 */, 17 }, + /* 3437 */ { MAD_F(0x0654e640) /* 0.395727395 */, 17 }, + /* 3438 */ { MAD_F(0x0655873b) /* 0.395880919 */, 17 }, + /* 3439 */ { MAD_F(0x0656283a) /* 0.396034458 */, 17 }, + + /* 3440 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 17 }, + /* 3441 */ { MAD_F(0x06576a45) /* 0.396341581 */, 17 }, + /* 3442 */ { MAD_F(0x06580b50) /* 0.396495164 */, 17 }, + /* 3443 */ { MAD_F(0x0658ac5f) /* 0.396648763 */, 17 }, + /* 3444 */ { MAD_F(0x06594d73) /* 0.396802376 */, 17 }, + /* 3445 */ { MAD_F(0x0659ee8a) /* 0.396956004 */, 17 }, + /* 3446 */ { MAD_F(0x065a8fa5) /* 0.397109647 */, 17 }, + /* 3447 */ { MAD_F(0x065b30c4) /* 0.397263305 */, 17 }, + /* 3448 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 17 }, + /* 3449 */ { MAD_F(0x065c730f) /* 0.397570666 */, 17 }, + /* 3450 */ { MAD_F(0x065d143a) /* 0.397724368 */, 17 }, + /* 3451 */ { MAD_F(0x065db569) /* 0.397878085 */, 17 }, + /* 3452 */ { MAD_F(0x065e569c) /* 0.398031818 */, 17 }, + /* 3453 */ { MAD_F(0x065ef7d3) /* 0.398185565 */, 17 }, + /* 3454 */ { MAD_F(0x065f990e) /* 0.398339326 */, 17 }, + /* 3455 */ { MAD_F(0x06603a4e) /* 0.398493103 */, 17 }, + + /* 3456 */ { MAD_F(0x0660db91) /* 0.398646895 */, 17 }, + /* 3457 */ { MAD_F(0x06617cd8) /* 0.398800701 */, 17 }, + /* 3458 */ { MAD_F(0x06621e23) /* 0.398954522 */, 17 }, + /* 3459 */ { MAD_F(0x0662bf72) /* 0.399108358 */, 17 }, + /* 3460 */ { MAD_F(0x066360c5) /* 0.399262209 */, 17 }, + /* 3461 */ { MAD_F(0x0664021c) /* 0.399416075 */, 17 }, + /* 3462 */ { MAD_F(0x0664a377) /* 0.399569955 */, 17 }, + /* 3463 */ { MAD_F(0x066544d6) /* 0.399723851 */, 17 }, + /* 3464 */ { MAD_F(0x0665e639) /* 0.399877761 */, 17 }, + /* 3465 */ { MAD_F(0x066687a0) /* 0.400031686 */, 17 }, + /* 3466 */ { MAD_F(0x0667290b) /* 0.400185625 */, 17 }, + /* 3467 */ { MAD_F(0x0667ca79) /* 0.400339580 */, 17 }, + /* 3468 */ { MAD_F(0x06686bec) /* 0.400493549 */, 17 }, + /* 3469 */ { MAD_F(0x06690d63) /* 0.400647534 */, 17 }, + /* 3470 */ { MAD_F(0x0669aede) /* 0.400801533 */, 17 }, + /* 3471 */ { MAD_F(0x066a505d) /* 0.400955546 */, 17 }, + + /* 3472 */ { MAD_F(0x066af1df) /* 0.401109575 */, 17 }, + /* 3473 */ { MAD_F(0x066b9366) /* 0.401263618 */, 17 }, + /* 3474 */ { MAD_F(0x066c34f1) /* 0.401417676 */, 17 }, + /* 3475 */ { MAD_F(0x066cd67f) /* 0.401571749 */, 17 }, + /* 3476 */ { MAD_F(0x066d7812) /* 0.401725837 */, 17 }, + /* 3477 */ { MAD_F(0x066e19a9) /* 0.401879939 */, 17 }, + /* 3478 */ { MAD_F(0x066ebb43) /* 0.402034056 */, 17 }, + /* 3479 */ { MAD_F(0x066f5ce2) /* 0.402188188 */, 17 }, + /* 3480 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 17 }, + /* 3481 */ { MAD_F(0x0670a02a) /* 0.402496497 */, 17 }, + /* 3482 */ { MAD_F(0x067141d5) /* 0.402650673 */, 17 }, + /* 3483 */ { MAD_F(0x0671e383) /* 0.402804864 */, 17 }, + /* 3484 */ { MAD_F(0x06728535) /* 0.402959070 */, 17 }, + /* 3485 */ { MAD_F(0x067326ec) /* 0.403113291 */, 17 }, + /* 3486 */ { MAD_F(0x0673c8a6) /* 0.403267526 */, 17 }, + /* 3487 */ { MAD_F(0x06746a64) /* 0.403421776 */, 17 }, + + /* 3488 */ { MAD_F(0x06750c26) /* 0.403576041 */, 17 }, + /* 3489 */ { MAD_F(0x0675adec) /* 0.403730320 */, 17 }, + /* 3490 */ { MAD_F(0x06764fb6) /* 0.403884615 */, 17 }, + /* 3491 */ { MAD_F(0x0676f184) /* 0.404038924 */, 17 }, + /* 3492 */ { MAD_F(0x06779356) /* 0.404193247 */, 17 }, + /* 3493 */ { MAD_F(0x0678352c) /* 0.404347586 */, 17 }, + /* 3494 */ { MAD_F(0x0678d706) /* 0.404501939 */, 17 }, + /* 3495 */ { MAD_F(0x067978e4) /* 0.404656307 */, 17 }, + /* 3496 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 17 }, + /* 3497 */ { MAD_F(0x067abcac) /* 0.404965087 */, 17 }, + /* 3498 */ { MAD_F(0x067b5e95) /* 0.405119499 */, 17 }, + /* 3499 */ { MAD_F(0x067c0083) /* 0.405273926 */, 17 }, + /* 3500 */ { MAD_F(0x067ca275) /* 0.405428368 */, 17 }, + /* 3501 */ { MAD_F(0x067d446a) /* 0.405582824 */, 17 }, + /* 3502 */ { MAD_F(0x067de664) /* 0.405737295 */, 17 }, + /* 3503 */ { MAD_F(0x067e8861) /* 0.405891781 */, 17 }, + + /* 3504 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 17 }, + /* 3505 */ { MAD_F(0x067fcc68) /* 0.406200796 */, 17 }, + /* 3506 */ { MAD_F(0x06806e71) /* 0.406355326 */, 17 }, + /* 3507 */ { MAD_F(0x0681107e) /* 0.406509870 */, 17 }, + /* 3508 */ { MAD_F(0x0681b28f) /* 0.406664429 */, 17 }, + /* 3509 */ { MAD_F(0x068254a4) /* 0.406819003 */, 17 }, + /* 3510 */ { MAD_F(0x0682f6bd) /* 0.406973592 */, 17 }, + /* 3511 */ { MAD_F(0x068398da) /* 0.407128195 */, 17 }, + /* 3512 */ { MAD_F(0x06843afb) /* 0.407282813 */, 17 }, + /* 3513 */ { MAD_F(0x0684dd20) /* 0.407437445 */, 17 }, + /* 3514 */ { MAD_F(0x06857f49) /* 0.407592093 */, 17 }, + /* 3515 */ { MAD_F(0x06862176) /* 0.407746754 */, 17 }, + /* 3516 */ { MAD_F(0x0686c3a6) /* 0.407901431 */, 17 }, + /* 3517 */ { MAD_F(0x068765db) /* 0.408056122 */, 17 }, + /* 3518 */ { MAD_F(0x06880814) /* 0.408210828 */, 17 }, + /* 3519 */ { MAD_F(0x0688aa50) /* 0.408365549 */, 17 }, + + /* 3520 */ { MAD_F(0x06894c90) /* 0.408520284 */, 17 }, + /* 3521 */ { MAD_F(0x0689eed5) /* 0.408675034 */, 17 }, + /* 3522 */ { MAD_F(0x068a911d) /* 0.408829798 */, 17 }, + /* 3523 */ { MAD_F(0x068b3369) /* 0.408984577 */, 17 }, + /* 3524 */ { MAD_F(0x068bd5b9) /* 0.409139371 */, 17 }, + /* 3525 */ { MAD_F(0x068c780e) /* 0.409294180 */, 17 }, + /* 3526 */ { MAD_F(0x068d1a66) /* 0.409449003 */, 17 }, + /* 3527 */ { MAD_F(0x068dbcc1) /* 0.409603840 */, 17 }, + /* 3528 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 17 }, + /* 3529 */ { MAD_F(0x068f0185) /* 0.409913560 */, 17 }, + /* 3530 */ { MAD_F(0x068fa3ed) /* 0.410068441 */, 17 }, + /* 3531 */ { MAD_F(0x06904658) /* 0.410223338 */, 17 }, + /* 3532 */ { MAD_F(0x0690e8c8) /* 0.410378249 */, 17 }, + /* 3533 */ { MAD_F(0x06918b3c) /* 0.410533174 */, 17 }, + /* 3534 */ { MAD_F(0x06922db3) /* 0.410688114 */, 17 }, + /* 3535 */ { MAD_F(0x0692d02e) /* 0.410843069 */, 17 }, + + /* 3536 */ { MAD_F(0x069372ae) /* 0.410998038 */, 17 }, + /* 3537 */ { MAD_F(0x06941531) /* 0.411153022 */, 17 }, + /* 3538 */ { MAD_F(0x0694b7b8) /* 0.411308021 */, 17 }, + /* 3539 */ { MAD_F(0x06955a43) /* 0.411463034 */, 17 }, + /* 3540 */ { MAD_F(0x0695fcd2) /* 0.411618062 */, 17 }, + /* 3541 */ { MAD_F(0x06969f65) /* 0.411773104 */, 17 }, + /* 3542 */ { MAD_F(0x069741fb) /* 0.411928161 */, 17 }, + /* 3543 */ { MAD_F(0x0697e496) /* 0.412083232 */, 17 }, + /* 3544 */ { MAD_F(0x06988735) /* 0.412238319 */, 17 }, + /* 3545 */ { MAD_F(0x069929d7) /* 0.412393419 */, 17 }, + /* 3546 */ { MAD_F(0x0699cc7e) /* 0.412548535 */, 17 }, + /* 3547 */ { MAD_F(0x069a6f28) /* 0.412703664 */, 17 }, + /* 3548 */ { MAD_F(0x069b11d6) /* 0.412858809 */, 17 }, + /* 3549 */ { MAD_F(0x069bb489) /* 0.413013968 */, 17 }, + /* 3550 */ { MAD_F(0x069c573f) /* 0.413169142 */, 17 }, + /* 3551 */ { MAD_F(0x069cf9f9) /* 0.413324330 */, 17 }, + + /* 3552 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 17 }, + /* 3553 */ { MAD_F(0x069e3f78) /* 0.413634750 */, 17 }, + /* 3554 */ { MAD_F(0x069ee23e) /* 0.413789982 */, 17 }, + /* 3555 */ { MAD_F(0x069f8508) /* 0.413945228 */, 17 }, + /* 3556 */ { MAD_F(0x06a027d5) /* 0.414100489 */, 17 }, + /* 3557 */ { MAD_F(0x06a0caa7) /* 0.414255765 */, 17 }, + /* 3558 */ { MAD_F(0x06a16d7c) /* 0.414411055 */, 17 }, + /* 3559 */ { MAD_F(0x06a21055) /* 0.414566359 */, 17 }, + /* 3560 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 17 }, + /* 3561 */ { MAD_F(0x06a35614) /* 0.414877012 */, 17 }, + /* 3562 */ { MAD_F(0x06a3f8f9) /* 0.415032361 */, 17 }, + /* 3563 */ { MAD_F(0x06a49be2) /* 0.415187723 */, 17 }, + /* 3564 */ { MAD_F(0x06a53ece) /* 0.415343101 */, 17 }, + /* 3565 */ { MAD_F(0x06a5e1bf) /* 0.415498493 */, 17 }, + /* 3566 */ { MAD_F(0x06a684b4) /* 0.415653899 */, 17 }, + /* 3567 */ { MAD_F(0x06a727ac) /* 0.415809320 */, 17 }, + + /* 3568 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 17 }, + /* 3569 */ { MAD_F(0x06a86da9) /* 0.416120206 */, 17 }, + /* 3570 */ { MAD_F(0x06a910ad) /* 0.416275670 */, 17 }, + /* 3571 */ { MAD_F(0x06a9b3b5) /* 0.416431149 */, 17 }, + /* 3572 */ { MAD_F(0x06aa56c1) /* 0.416586643 */, 17 }, + /* 3573 */ { MAD_F(0x06aaf9d1) /* 0.416742151 */, 17 }, + /* 3574 */ { MAD_F(0x06ab9ce5) /* 0.416897673 */, 17 }, + /* 3575 */ { MAD_F(0x06ac3ffc) /* 0.417053210 */, 17 }, + /* 3576 */ { MAD_F(0x06ace318) /* 0.417208762 */, 17 }, + /* 3577 */ { MAD_F(0x06ad8637) /* 0.417364328 */, 17 }, + /* 3578 */ { MAD_F(0x06ae295b) /* 0.417519909 */, 17 }, + /* 3579 */ { MAD_F(0x06aecc82) /* 0.417675504 */, 17 }, + /* 3580 */ { MAD_F(0x06af6fad) /* 0.417831113 */, 17 }, + /* 3581 */ { MAD_F(0x06b012dc) /* 0.417986737 */, 17 }, + /* 3582 */ { MAD_F(0x06b0b60f) /* 0.418142376 */, 17 }, + /* 3583 */ { MAD_F(0x06b15946) /* 0.418298029 */, 17 }, + + /* 3584 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 17 }, + /* 3585 */ { MAD_F(0x06b29fbf) /* 0.418609378 */, 17 }, + /* 3586 */ { MAD_F(0x06b34302) /* 0.418765075 */, 17 }, + /* 3587 */ { MAD_F(0x06b3e648) /* 0.418920786 */, 17 }, + /* 3588 */ { MAD_F(0x06b48992) /* 0.419076511 */, 17 }, + /* 3589 */ { MAD_F(0x06b52ce0) /* 0.419232251 */, 17 }, + /* 3590 */ { MAD_F(0x06b5d032) /* 0.419388005 */, 17 }, + /* 3591 */ { MAD_F(0x06b67388) /* 0.419543774 */, 17 }, + /* 3592 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 17 }, + /* 3593 */ { MAD_F(0x06b7ba3f) /* 0.419855355 */, 17 }, + /* 3594 */ { MAD_F(0x06b85da1) /* 0.420011167 */, 17 }, + /* 3595 */ { MAD_F(0x06b90106) /* 0.420166994 */, 17 }, + /* 3596 */ { MAD_F(0x06b9a470) /* 0.420322835 */, 17 }, + /* 3597 */ { MAD_F(0x06ba47dd) /* 0.420478690 */, 17 }, + /* 3598 */ { MAD_F(0x06baeb4e) /* 0.420634560 */, 17 }, + /* 3599 */ { MAD_F(0x06bb8ec3) /* 0.420790445 */, 17 }, + + /* 3600 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 17 }, + /* 3601 */ { MAD_F(0x06bcd5b8) /* 0.421102257 */, 17 }, + /* 3602 */ { MAD_F(0x06bd7939) /* 0.421258184 */, 17 }, + /* 3603 */ { MAD_F(0x06be1cbd) /* 0.421414127 */, 17 }, + /* 3604 */ { MAD_F(0x06bec045) /* 0.421570083 */, 17 }, + /* 3605 */ { MAD_F(0x06bf63d1) /* 0.421726054 */, 17 }, + /* 3606 */ { MAD_F(0x06c00761) /* 0.421882040 */, 17 }, + /* 3607 */ { MAD_F(0x06c0aaf5) /* 0.422038039 */, 17 }, + /* 3608 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 17 }, + /* 3609 */ { MAD_F(0x06c1f229) /* 0.422350082 */, 17 }, + /* 3610 */ { MAD_F(0x06c295c8) /* 0.422506125 */, 17 }, + /* 3611 */ { MAD_F(0x06c3396c) /* 0.422662183 */, 17 }, + /* 3612 */ { MAD_F(0x06c3dd13) /* 0.422818255 */, 17 }, + /* 3613 */ { MAD_F(0x06c480be) /* 0.422974341 */, 17 }, + /* 3614 */ { MAD_F(0x06c5246d) /* 0.423130442 */, 17 }, + /* 3615 */ { MAD_F(0x06c5c820) /* 0.423286557 */, 17 }, + + /* 3616 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 17 }, + /* 3617 */ { MAD_F(0x06c70f91) /* 0.423598830 */, 17 }, + /* 3618 */ { MAD_F(0x06c7b34f) /* 0.423754988 */, 17 }, + /* 3619 */ { MAD_F(0x06c85712) /* 0.423911161 */, 17 }, + /* 3620 */ { MAD_F(0x06c8fad8) /* 0.424067348 */, 17 }, + /* 3621 */ { MAD_F(0x06c99ea2) /* 0.424223550 */, 17 }, + /* 3622 */ { MAD_F(0x06ca4270) /* 0.424379765 */, 17 }, + /* 3623 */ { MAD_F(0x06cae641) /* 0.424535996 */, 17 }, + /* 3624 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 17 }, + /* 3625 */ { MAD_F(0x06cc2df0) /* 0.424848499 */, 17 }, + /* 3626 */ { MAD_F(0x06ccd1ce) /* 0.425004772 */, 17 }, + /* 3627 */ { MAD_F(0x06cd75af) /* 0.425161060 */, 17 }, + /* 3628 */ { MAD_F(0x06ce1994) /* 0.425317362 */, 17 }, + /* 3629 */ { MAD_F(0x06cebd7d) /* 0.425473678 */, 17 }, + /* 3630 */ { MAD_F(0x06cf6169) /* 0.425630009 */, 17 }, + /* 3631 */ { MAD_F(0x06d0055a) /* 0.425786354 */, 17 }, + + /* 3632 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 17 }, + /* 3633 */ { MAD_F(0x06d14d47) /* 0.426099088 */, 17 }, + /* 3634 */ { MAD_F(0x06d1f143) /* 0.426255476 */, 17 }, + /* 3635 */ { MAD_F(0x06d29543) /* 0.426411878 */, 17 }, + /* 3636 */ { MAD_F(0x06d33947) /* 0.426568295 */, 17 }, + /* 3637 */ { MAD_F(0x06d3dd4e) /* 0.426724726 */, 17 }, + /* 3638 */ { MAD_F(0x06d4815a) /* 0.426881172 */, 17 }, + /* 3639 */ { MAD_F(0x06d52569) /* 0.427037632 */, 17 }, + /* 3640 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 17 }, + /* 3641 */ { MAD_F(0x06d66d93) /* 0.427350594 */, 17 }, + /* 3642 */ { MAD_F(0x06d711ae) /* 0.427507097 */, 17 }, + /* 3643 */ { MAD_F(0x06d7b5cd) /* 0.427663614 */, 17 }, + /* 3644 */ { MAD_F(0x06d859f0) /* 0.427820146 */, 17 }, + /* 3645 */ { MAD_F(0x06d8fe16) /* 0.427976692 */, 17 }, + /* 3646 */ { MAD_F(0x06d9a240) /* 0.428133252 */, 17 }, + /* 3647 */ { MAD_F(0x06da466f) /* 0.428289826 */, 17 }, + + /* 3648 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 17 }, + /* 3649 */ { MAD_F(0x06db8ed6) /* 0.428603018 */, 17 }, + /* 3650 */ { MAD_F(0x06dc3310) /* 0.428759635 */, 17 }, + /* 3651 */ { MAD_F(0x06dcd74d) /* 0.428916267 */, 17 }, + /* 3652 */ { MAD_F(0x06dd7b8f) /* 0.429072913 */, 17 }, + /* 3653 */ { MAD_F(0x06de1fd4) /* 0.429229573 */, 17 }, + /* 3654 */ { MAD_F(0x06dec41d) /* 0.429386248 */, 17 }, + /* 3655 */ { MAD_F(0x06df686a) /* 0.429542937 */, 17 }, + /* 3656 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 17 }, + /* 3657 */ { MAD_F(0x06e0b10f) /* 0.429856357 */, 17 }, + /* 3658 */ { MAD_F(0x06e15567) /* 0.430013089 */, 17 }, + /* 3659 */ { MAD_F(0x06e1f9c4) /* 0.430169835 */, 17 }, + /* 3660 */ { MAD_F(0x06e29e24) /* 0.430326595 */, 17 }, + /* 3661 */ { MAD_F(0x06e34287) /* 0.430483370 */, 17 }, + /* 3662 */ { MAD_F(0x06e3e6ef) /* 0.430640159 */, 17 }, + /* 3663 */ { MAD_F(0x06e48b5b) /* 0.430796962 */, 17 }, + + /* 3664 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 17 }, + /* 3665 */ { MAD_F(0x06e5d43d) /* 0.431110611 */, 17 }, + /* 3666 */ { MAD_F(0x06e678b4) /* 0.431267457 */, 17 }, + /* 3667 */ { MAD_F(0x06e71d2f) /* 0.431424317 */, 17 }, + /* 3668 */ { MAD_F(0x06e7c1ae) /* 0.431581192 */, 17 }, + /* 3669 */ { MAD_F(0x06e86630) /* 0.431738080 */, 17 }, + /* 3670 */ { MAD_F(0x06e90ab7) /* 0.431894983 */, 17 }, + /* 3671 */ { MAD_F(0x06e9af41) /* 0.432051900 */, 17 }, + /* 3672 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 17 }, + /* 3673 */ { MAD_F(0x06eaf860) /* 0.432365778 */, 17 }, + /* 3674 */ { MAD_F(0x06eb9cf6) /* 0.432522737 */, 17 }, + /* 3675 */ { MAD_F(0x06ec418f) /* 0.432679712 */, 17 }, + /* 3676 */ { MAD_F(0x06ece62d) /* 0.432836700 */, 17 }, + /* 3677 */ { MAD_F(0x06ed8ace) /* 0.432993703 */, 17 }, + /* 3678 */ { MAD_F(0x06ee2f73) /* 0.433150720 */, 17 }, + /* 3679 */ { MAD_F(0x06eed41b) /* 0.433307751 */, 17 }, + + /* 3680 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 17 }, + /* 3681 */ { MAD_F(0x06f01d78) /* 0.433621856 */, 17 }, + /* 3682 */ { MAD_F(0x06f0c22c) /* 0.433778929 */, 17 }, + /* 3683 */ { MAD_F(0x06f166e4) /* 0.433936017 */, 17 }, + /* 3684 */ { MAD_F(0x06f20ba0) /* 0.434093120 */, 17 }, + /* 3685 */ { MAD_F(0x06f2b060) /* 0.434250236 */, 17 }, + /* 3686 */ { MAD_F(0x06f35523) /* 0.434407367 */, 17 }, + /* 3687 */ { MAD_F(0x06f3f9eb) /* 0.434564512 */, 17 }, + /* 3688 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 17 }, + /* 3689 */ { MAD_F(0x06f54385) /* 0.434878844 */, 17 }, + /* 3690 */ { MAD_F(0x06f5e857) /* 0.435036032 */, 17 }, + /* 3691 */ { MAD_F(0x06f68d2e) /* 0.435193233 */, 17 }, + /* 3692 */ { MAD_F(0x06f73208) /* 0.435350449 */, 17 }, + /* 3693 */ { MAD_F(0x06f7d6e6) /* 0.435507679 */, 17 }, + /* 3694 */ { MAD_F(0x06f87bc8) /* 0.435664924 */, 17 }, + /* 3695 */ { MAD_F(0x06f920ae) /* 0.435822182 */, 17 }, + + /* 3696 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 17 }, + /* 3697 */ { MAD_F(0x06fa6a85) /* 0.436136741 */, 17 }, + /* 3698 */ { MAD_F(0x06fb0f76) /* 0.436294042 */, 17 }, + /* 3699 */ { MAD_F(0x06fbb46b) /* 0.436451358 */, 17 }, + /* 3700 */ { MAD_F(0x06fc5964) /* 0.436608687 */, 17 }, + /* 3701 */ { MAD_F(0x06fcfe60) /* 0.436766031 */, 17 }, + /* 3702 */ { MAD_F(0x06fda361) /* 0.436923388 */, 17 }, + /* 3703 */ { MAD_F(0x06fe4865) /* 0.437080760 */, 17 }, + /* 3704 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 17 }, + /* 3705 */ { MAD_F(0x06ff9279) /* 0.437395547 */, 17 }, + /* 3706 */ { MAD_F(0x07003788) /* 0.437552961 */, 17 }, + /* 3707 */ { MAD_F(0x0700dc9c) /* 0.437710389 */, 17 }, + /* 3708 */ { MAD_F(0x070181b3) /* 0.437867832 */, 17 }, + /* 3709 */ { MAD_F(0x070226ce) /* 0.438025289 */, 17 }, + /* 3710 */ { MAD_F(0x0702cbed) /* 0.438182760 */, 17 }, + /* 3711 */ { MAD_F(0x0703710f) /* 0.438340245 */, 17 }, + + /* 3712 */ { MAD_F(0x07041636) /* 0.438497744 */, 17 }, + /* 3713 */ { MAD_F(0x0704bb60) /* 0.438655258 */, 17 }, + /* 3714 */ { MAD_F(0x0705608e) /* 0.438812785 */, 17 }, + /* 3715 */ { MAD_F(0x070605c0) /* 0.438970327 */, 17 }, + /* 3716 */ { MAD_F(0x0706aaf5) /* 0.439127883 */, 17 }, + /* 3717 */ { MAD_F(0x0707502f) /* 0.439285453 */, 17 }, + /* 3718 */ { MAD_F(0x0707f56c) /* 0.439443037 */, 17 }, + /* 3719 */ { MAD_F(0x07089aad) /* 0.439600635 */, 17 }, + /* 3720 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 17 }, + /* 3721 */ { MAD_F(0x0709e53a) /* 0.439915874 */, 17 }, + /* 3722 */ { MAD_F(0x070a8a86) /* 0.440073515 */, 17 }, + /* 3723 */ { MAD_F(0x070b2fd7) /* 0.440231170 */, 17 }, + /* 3724 */ { MAD_F(0x070bd52a) /* 0.440388839 */, 17 }, + /* 3725 */ { MAD_F(0x070c7a82) /* 0.440546522 */, 17 }, + /* 3726 */ { MAD_F(0x070d1fde) /* 0.440704219 */, 17 }, + /* 3727 */ { MAD_F(0x070dc53d) /* 0.440861930 */, 17 }, + + /* 3728 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 17 }, + /* 3729 */ { MAD_F(0x070f1007) /* 0.441177395 */, 17 }, + /* 3730 */ { MAD_F(0x070fb571) /* 0.441335148 */, 17 }, + /* 3731 */ { MAD_F(0x07105ae0) /* 0.441492916 */, 17 }, + /* 3732 */ { MAD_F(0x07110052) /* 0.441650697 */, 17 }, + /* 3733 */ { MAD_F(0x0711a5c8) /* 0.441808493 */, 17 }, + /* 3734 */ { MAD_F(0x07124b42) /* 0.441966303 */, 17 }, + /* 3735 */ { MAD_F(0x0712f0bf) /* 0.442124127 */, 17 }, + /* 3736 */ { MAD_F(0x07139641) /* 0.442281965 */, 17 }, + /* 3737 */ { MAD_F(0x07143bc6) /* 0.442439817 */, 17 }, + /* 3738 */ { MAD_F(0x0714e14f) /* 0.442597683 */, 17 }, + /* 3739 */ { MAD_F(0x071586db) /* 0.442755564 */, 17 }, + /* 3740 */ { MAD_F(0x07162c6c) /* 0.442913458 */, 17 }, + /* 3741 */ { MAD_F(0x0716d200) /* 0.443071366 */, 17 }, + /* 3742 */ { MAD_F(0x07177798) /* 0.443229289 */, 17 }, + /* 3743 */ { MAD_F(0x07181d34) /* 0.443387226 */, 17 }, + + /* 3744 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 17 }, + /* 3745 */ { MAD_F(0x07196877) /* 0.443703141 */, 17 }, + /* 3746 */ { MAD_F(0x071a0e1e) /* 0.443861120 */, 17 }, + /* 3747 */ { MAD_F(0x071ab3c9) /* 0.444019113 */, 17 }, + /* 3748 */ { MAD_F(0x071b5977) /* 0.444177119 */, 17 }, + /* 3749 */ { MAD_F(0x071bff2a) /* 0.444335140 */, 17 }, + /* 3750 */ { MAD_F(0x071ca4e0) /* 0.444493175 */, 17 }, + /* 3751 */ { MAD_F(0x071d4a9a) /* 0.444651224 */, 17 }, + /* 3752 */ { MAD_F(0x071df058) /* 0.444809288 */, 17 }, + /* 3753 */ { MAD_F(0x071e9619) /* 0.444967365 */, 17 }, + /* 3754 */ { MAD_F(0x071f3bde) /* 0.445125456 */, 17 }, + /* 3755 */ { MAD_F(0x071fe1a8) /* 0.445283561 */, 17 }, + /* 3756 */ { MAD_F(0x07208774) /* 0.445441680 */, 17 }, + /* 3757 */ { MAD_F(0x07212d45) /* 0.445599814 */, 17 }, + /* 3758 */ { MAD_F(0x0721d319) /* 0.445757961 */, 17 }, + /* 3759 */ { MAD_F(0x072278f1) /* 0.445916122 */, 17 }, + + /* 3760 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 17 }, + /* 3761 */ { MAD_F(0x0723c4ad) /* 0.446232487 */, 17 }, + /* 3762 */ { MAD_F(0x07246a90) /* 0.446390690 */, 17 }, + /* 3763 */ { MAD_F(0x07251077) /* 0.446548908 */, 17 }, + /* 3764 */ { MAD_F(0x0725b662) /* 0.446707139 */, 17 }, + /* 3765 */ { MAD_F(0x07265c51) /* 0.446865385 */, 17 }, + /* 3766 */ { MAD_F(0x07270244) /* 0.447023644 */, 17 }, + /* 3767 */ { MAD_F(0x0727a83a) /* 0.447181918 */, 17 }, + /* 3768 */ { MAD_F(0x07284e34) /* 0.447340205 */, 17 }, + /* 3769 */ { MAD_F(0x0728f431) /* 0.447498507 */, 17 }, + /* 3770 */ { MAD_F(0x07299a33) /* 0.447656822 */, 17 }, + /* 3771 */ { MAD_F(0x072a4038) /* 0.447815152 */, 17 }, + /* 3772 */ { MAD_F(0x072ae641) /* 0.447973495 */, 17 }, + /* 3773 */ { MAD_F(0x072b8c4e) /* 0.448131853 */, 17 }, + /* 3774 */ { MAD_F(0x072c325e) /* 0.448290224 */, 17 }, + /* 3775 */ { MAD_F(0x072cd873) /* 0.448448609 */, 17 }, + + /* 3776 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 17 }, + /* 3777 */ { MAD_F(0x072e24a7) /* 0.448765422 */, 17 }, + /* 3778 */ { MAD_F(0x072ecac6) /* 0.448923850 */, 17 }, + /* 3779 */ { MAD_F(0x072f70e9) /* 0.449082291 */, 17 }, + /* 3780 */ { MAD_F(0x07301710) /* 0.449240746 */, 17 }, + /* 3781 */ { MAD_F(0x0730bd3b) /* 0.449399216 */, 17 }, + /* 3782 */ { MAD_F(0x0731636a) /* 0.449557699 */, 17 }, + /* 3783 */ { MAD_F(0x0732099c) /* 0.449716196 */, 17 }, + /* 3784 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 17 }, + /* 3785 */ { MAD_F(0x0733560c) /* 0.450033233 */, 17 }, + /* 3786 */ { MAD_F(0x0733fc49) /* 0.450191772 */, 17 }, + /* 3787 */ { MAD_F(0x0734a28b) /* 0.450350325 */, 17 }, + /* 3788 */ { MAD_F(0x073548d0) /* 0.450508892 */, 17 }, + /* 3789 */ { MAD_F(0x0735ef18) /* 0.450667473 */, 17 }, + /* 3790 */ { MAD_F(0x07369565) /* 0.450826068 */, 17 }, + /* 3791 */ { MAD_F(0x07373bb5) /* 0.450984677 */, 17 }, + + /* 3792 */ { MAD_F(0x0737e209) /* 0.451143300 */, 17 }, + /* 3793 */ { MAD_F(0x07388861) /* 0.451301937 */, 17 }, + /* 3794 */ { MAD_F(0x07392ebc) /* 0.451460588 */, 17 }, + /* 3795 */ { MAD_F(0x0739d51c) /* 0.451619252 */, 17 }, + /* 3796 */ { MAD_F(0x073a7b7f) /* 0.451777931 */, 17 }, + /* 3797 */ { MAD_F(0x073b21e5) /* 0.451936623 */, 17 }, + /* 3798 */ { MAD_F(0x073bc850) /* 0.452095330 */, 17 }, + /* 3799 */ { MAD_F(0x073c6ebe) /* 0.452254050 */, 17 }, + /* 3800 */ { MAD_F(0x073d1530) /* 0.452412785 */, 17 }, + /* 3801 */ { MAD_F(0x073dbba6) /* 0.452571533 */, 17 }, + /* 3802 */ { MAD_F(0x073e621f) /* 0.452730295 */, 17 }, + /* 3803 */ { MAD_F(0x073f089c) /* 0.452889071 */, 17 }, + /* 3804 */ { MAD_F(0x073faf1d) /* 0.453047861 */, 17 }, + /* 3805 */ { MAD_F(0x074055a2) /* 0.453206665 */, 17 }, + /* 3806 */ { MAD_F(0x0740fc2a) /* 0.453365483 */, 17 }, + /* 3807 */ { MAD_F(0x0741a2b6) /* 0.453524315 */, 17 }, + + /* 3808 */ { MAD_F(0x07424946) /* 0.453683161 */, 17 }, + /* 3809 */ { MAD_F(0x0742efd9) /* 0.453842020 */, 17 }, + /* 3810 */ { MAD_F(0x07439671) /* 0.454000894 */, 17 }, + /* 3811 */ { MAD_F(0x07443d0c) /* 0.454159781 */, 17 }, + /* 3812 */ { MAD_F(0x0744e3aa) /* 0.454318683 */, 17 }, + /* 3813 */ { MAD_F(0x07458a4d) /* 0.454477598 */, 17 }, + /* 3814 */ { MAD_F(0x074630f3) /* 0.454636527 */, 17 }, + /* 3815 */ { MAD_F(0x0746d79d) /* 0.454795470 */, 17 }, + /* 3816 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 17 }, + /* 3817 */ { MAD_F(0x074824fc) /* 0.455113397 */, 17 }, + /* 3818 */ { MAD_F(0x0748cbb1) /* 0.455272382 */, 17 }, + /* 3819 */ { MAD_F(0x0749726a) /* 0.455431381 */, 17 }, + /* 3820 */ { MAD_F(0x074a1927) /* 0.455590393 */, 17 }, + /* 3821 */ { MAD_F(0x074abfe7) /* 0.455749419 */, 17 }, + /* 3822 */ { MAD_F(0x074b66ab) /* 0.455908459 */, 17 }, + /* 3823 */ { MAD_F(0x074c0d73) /* 0.456067513 */, 17 }, + + /* 3824 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 17 }, + /* 3825 */ { MAD_F(0x074d5b0d) /* 0.456385663 */, 17 }, + /* 3826 */ { MAD_F(0x074e01e0) /* 0.456544759 */, 17 }, + /* 3827 */ { MAD_F(0x074ea8b7) /* 0.456703868 */, 17 }, + /* 3828 */ { MAD_F(0x074f4f91) /* 0.456862992 */, 17 }, + /* 3829 */ { MAD_F(0x074ff66f) /* 0.457022129 */, 17 }, + /* 3830 */ { MAD_F(0x07509d51) /* 0.457181280 */, 17 }, + /* 3831 */ { MAD_F(0x07514437) /* 0.457340445 */, 17 }, + /* 3832 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 17 }, + /* 3833 */ { MAD_F(0x0752920d) /* 0.457658816 */, 17 }, + /* 3834 */ { MAD_F(0x075338fd) /* 0.457818022 */, 17 }, + /* 3835 */ { MAD_F(0x0753dff2) /* 0.457977243 */, 17 }, + /* 3836 */ { MAD_F(0x075486ea) /* 0.458136477 */, 17 }, + /* 3837 */ { MAD_F(0x07552de6) /* 0.458295725 */, 17 }, + /* 3838 */ { MAD_F(0x0755d4e5) /* 0.458454987 */, 17 }, + /* 3839 */ { MAD_F(0x07567be8) /* 0.458614262 */, 17 }, + + /* 3840 */ { MAD_F(0x075722ef) /* 0.458773552 */, 17 }, + /* 3841 */ { MAD_F(0x0757c9fa) /* 0.458932855 */, 17 }, + /* 3842 */ { MAD_F(0x07587108) /* 0.459092172 */, 17 }, + /* 3843 */ { MAD_F(0x0759181a) /* 0.459251503 */, 17 }, + /* 3844 */ { MAD_F(0x0759bf30) /* 0.459410848 */, 17 }, + /* 3845 */ { MAD_F(0x075a664a) /* 0.459570206 */, 17 }, + /* 3846 */ { MAD_F(0x075b0d67) /* 0.459729579 */, 17 }, + /* 3847 */ { MAD_F(0x075bb488) /* 0.459888965 */, 17 }, + /* 3848 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 17 }, + /* 3849 */ { MAD_F(0x075d02d5) /* 0.460207779 */, 17 }, + /* 3850 */ { MAD_F(0x075daa01) /* 0.460367206 */, 17 }, + /* 3851 */ { MAD_F(0x075e5130) /* 0.460526648 */, 17 }, + /* 3852 */ { MAD_F(0x075ef864) /* 0.460686103 */, 17 }, + /* 3853 */ { MAD_F(0x075f9f9b) /* 0.460845572 */, 17 }, + /* 3854 */ { MAD_F(0x076046d6) /* 0.461005055 */, 17 }, + /* 3855 */ { MAD_F(0x0760ee14) /* 0.461164552 */, 17 }, + + /* 3856 */ { MAD_F(0x07619557) /* 0.461324062 */, 17 }, + /* 3857 */ { MAD_F(0x07623c9d) /* 0.461483586 */, 17 }, + /* 3858 */ { MAD_F(0x0762e3e6) /* 0.461643124 */, 17 }, + /* 3859 */ { MAD_F(0x07638b34) /* 0.461802676 */, 17 }, + /* 3860 */ { MAD_F(0x07643285) /* 0.461962242 */, 17 }, + /* 3861 */ { MAD_F(0x0764d9d9) /* 0.462121821 */, 17 }, + /* 3862 */ { MAD_F(0x07658132) /* 0.462281414 */, 17 }, + /* 3863 */ { MAD_F(0x0766288e) /* 0.462441021 */, 17 }, + /* 3864 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 17 }, + /* 3865 */ { MAD_F(0x07677751) /* 0.462760276 */, 17 }, + /* 3866 */ { MAD_F(0x07681eb9) /* 0.462919924 */, 17 }, + /* 3867 */ { MAD_F(0x0768c624) /* 0.463079586 */, 17 }, + /* 3868 */ { MAD_F(0x07696d92) /* 0.463239262 */, 17 }, + /* 3869 */ { MAD_F(0x076a1505) /* 0.463398951 */, 17 }, + /* 3870 */ { MAD_F(0x076abc7b) /* 0.463558655 */, 17 }, + /* 3871 */ { MAD_F(0x076b63f4) /* 0.463718372 */, 17 }, + + /* 3872 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 17 }, + /* 3873 */ { MAD_F(0x076cb2f3) /* 0.464037847 */, 17 }, + /* 3874 */ { MAD_F(0x076d5a78) /* 0.464197605 */, 17 }, + /* 3875 */ { MAD_F(0x076e0200) /* 0.464357377 */, 17 }, + /* 3876 */ { MAD_F(0x076ea98c) /* 0.464517163 */, 17 }, + /* 3877 */ { MAD_F(0x076f511c) /* 0.464676962 */, 17 }, + /* 3878 */ { MAD_F(0x076ff8b0) /* 0.464836776 */, 17 }, + /* 3879 */ { MAD_F(0x0770a047) /* 0.464996603 */, 17 }, + /* 3880 */ { MAD_F(0x077147e2) /* 0.465156443 */, 17 }, + /* 3881 */ { MAD_F(0x0771ef80) /* 0.465316298 */, 17 }, + /* 3882 */ { MAD_F(0x07729723) /* 0.465476166 */, 17 }, + /* 3883 */ { MAD_F(0x07733ec9) /* 0.465636048 */, 17 }, + /* 3884 */ { MAD_F(0x0773e672) /* 0.465795943 */, 17 }, + /* 3885 */ { MAD_F(0x07748e20) /* 0.465955853 */, 17 }, + /* 3886 */ { MAD_F(0x077535d1) /* 0.466115776 */, 17 }, + /* 3887 */ { MAD_F(0x0775dd85) /* 0.466275713 */, 17 }, + + /* 3888 */ { MAD_F(0x0776853e) /* 0.466435663 */, 17 }, + /* 3889 */ { MAD_F(0x07772cfa) /* 0.466595627 */, 17 }, + /* 3890 */ { MAD_F(0x0777d4ba) /* 0.466755605 */, 17 }, + /* 3891 */ { MAD_F(0x07787c7d) /* 0.466915597 */, 17 }, + /* 3892 */ { MAD_F(0x07792444) /* 0.467075602 */, 17 }, + /* 3893 */ { MAD_F(0x0779cc0f) /* 0.467235621 */, 17 }, + /* 3894 */ { MAD_F(0x077a73dd) /* 0.467395654 */, 17 }, + /* 3895 */ { MAD_F(0x077b1baf) /* 0.467555701 */, 17 }, + /* 3896 */ { MAD_F(0x077bc385) /* 0.467715761 */, 17 }, + /* 3897 */ { MAD_F(0x077c6b5f) /* 0.467875835 */, 17 }, + /* 3898 */ { MAD_F(0x077d133c) /* 0.468035922 */, 17 }, + /* 3899 */ { MAD_F(0x077dbb1d) /* 0.468196023 */, 17 }, + /* 3900 */ { MAD_F(0x077e6301) /* 0.468356138 */, 17 }, + /* 3901 */ { MAD_F(0x077f0ae9) /* 0.468516267 */, 17 }, + /* 3902 */ { MAD_F(0x077fb2d5) /* 0.468676409 */, 17 }, + /* 3903 */ { MAD_F(0x07805ac5) /* 0.468836565 */, 17 }, + + /* 3904 */ { MAD_F(0x078102b8) /* 0.468996735 */, 17 }, + /* 3905 */ { MAD_F(0x0781aaaf) /* 0.469156918 */, 17 }, + /* 3906 */ { MAD_F(0x078252aa) /* 0.469317115 */, 17 }, + /* 3907 */ { MAD_F(0x0782faa8) /* 0.469477326 */, 17 }, + /* 3908 */ { MAD_F(0x0783a2aa) /* 0.469637550 */, 17 }, + /* 3909 */ { MAD_F(0x07844aaf) /* 0.469797788 */, 17 }, + /* 3910 */ { MAD_F(0x0784f2b8) /* 0.469958040 */, 17 }, + /* 3911 */ { MAD_F(0x07859ac5) /* 0.470118305 */, 17 }, + /* 3912 */ { MAD_F(0x078642d6) /* 0.470278584 */, 17 }, + /* 3913 */ { MAD_F(0x0786eaea) /* 0.470438877 */, 17 }, + /* 3914 */ { MAD_F(0x07879302) /* 0.470599183 */, 17 }, + /* 3915 */ { MAD_F(0x07883b1e) /* 0.470759503 */, 17 }, + /* 3916 */ { MAD_F(0x0788e33d) /* 0.470919836 */, 17 }, + /* 3917 */ { MAD_F(0x07898b60) /* 0.471080184 */, 17 }, + /* 3918 */ { MAD_F(0x078a3386) /* 0.471240545 */, 17 }, + /* 3919 */ { MAD_F(0x078adbb0) /* 0.471400919 */, 17 }, + + /* 3920 */ { MAD_F(0x078b83de) /* 0.471561307 */, 17 }, + /* 3921 */ { MAD_F(0x078c2c10) /* 0.471721709 */, 17 }, + /* 3922 */ { MAD_F(0x078cd445) /* 0.471882125 */, 17 }, + /* 3923 */ { MAD_F(0x078d7c7e) /* 0.472042554 */, 17 }, + /* 3924 */ { MAD_F(0x078e24ba) /* 0.472202996 */, 17 }, + /* 3925 */ { MAD_F(0x078eccfb) /* 0.472363453 */, 17 }, + /* 3926 */ { MAD_F(0x078f753e) /* 0.472523923 */, 17 }, + /* 3927 */ { MAD_F(0x07901d86) /* 0.472684406 */, 17 }, + /* 3928 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 17 }, + /* 3929 */ { MAD_F(0x07916e20) /* 0.473005414 */, 17 }, + /* 3930 */ { MAD_F(0x07921672) /* 0.473165939 */, 17 }, + /* 3931 */ { MAD_F(0x0792bec8) /* 0.473326477 */, 17 }, + /* 3932 */ { MAD_F(0x07936722) /* 0.473487029 */, 17 }, + /* 3933 */ { MAD_F(0x07940f80) /* 0.473647594 */, 17 }, + /* 3934 */ { MAD_F(0x0794b7e1) /* 0.473808173 */, 17 }, + /* 3935 */ { MAD_F(0x07956045) /* 0.473968765 */, 17 }, + + /* 3936 */ { MAD_F(0x079608ae) /* 0.474129372 */, 17 }, + /* 3937 */ { MAD_F(0x0796b11a) /* 0.474289991 */, 17 }, + /* 3938 */ { MAD_F(0x0797598a) /* 0.474450625 */, 17 }, + /* 3939 */ { MAD_F(0x079801fd) /* 0.474611272 */, 17 }, + /* 3940 */ { MAD_F(0x0798aa74) /* 0.474771932 */, 17 }, + /* 3941 */ { MAD_F(0x079952ee) /* 0.474932606 */, 17 }, + /* 3942 */ { MAD_F(0x0799fb6d) /* 0.475093294 */, 17 }, + /* 3943 */ { MAD_F(0x079aa3ef) /* 0.475253995 */, 17 }, + /* 3944 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 17 }, + /* 3945 */ { MAD_F(0x079bf4fd) /* 0.475575439 */, 17 }, + /* 3946 */ { MAD_F(0x079c9d8a) /* 0.475736181 */, 17 }, + /* 3947 */ { MAD_F(0x079d461b) /* 0.475896936 */, 17 }, + /* 3948 */ { MAD_F(0x079deeaf) /* 0.476057705 */, 17 }, + /* 3949 */ { MAD_F(0x079e9747) /* 0.476218488 */, 17 }, + /* 3950 */ { MAD_F(0x079f3fe2) /* 0.476379285 */, 17 }, + /* 3951 */ { MAD_F(0x079fe881) /* 0.476540095 */, 17 }, + + /* 3952 */ { MAD_F(0x07a09124) /* 0.476700918 */, 17 }, + /* 3953 */ { MAD_F(0x07a139ca) /* 0.476861755 */, 17 }, + /* 3954 */ { MAD_F(0x07a1e274) /* 0.477022606 */, 17 }, + /* 3955 */ { MAD_F(0x07a28b22) /* 0.477183470 */, 17 }, + /* 3956 */ { MAD_F(0x07a333d3) /* 0.477344348 */, 17 }, + /* 3957 */ { MAD_F(0x07a3dc88) /* 0.477505239 */, 17 }, + /* 3958 */ { MAD_F(0x07a48541) /* 0.477666144 */, 17 }, + /* 3959 */ { MAD_F(0x07a52dfd) /* 0.477827062 */, 17 }, + /* 3960 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 17 }, + /* 3961 */ { MAD_F(0x07a67f80) /* 0.478148940 */, 17 }, + /* 3962 */ { MAD_F(0x07a72847) /* 0.478309899 */, 17 }, + /* 3963 */ { MAD_F(0x07a7d112) /* 0.478470871 */, 17 }, + /* 3964 */ { MAD_F(0x07a879e1) /* 0.478631857 */, 17 }, + /* 3965 */ { MAD_F(0x07a922b3) /* 0.478792857 */, 17 }, + /* 3966 */ { MAD_F(0x07a9cb88) /* 0.478953870 */, 17 }, + /* 3967 */ { MAD_F(0x07aa7462) /* 0.479114897 */, 17 }, + + /* 3968 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 17 }, + /* 3969 */ { MAD_F(0x07abc61f) /* 0.479436991 */, 17 }, + /* 3970 */ { MAD_F(0x07ac6f03) /* 0.479598058 */, 17 }, + /* 3971 */ { MAD_F(0x07ad17eb) /* 0.479759139 */, 17 }, + /* 3972 */ { MAD_F(0x07adc0d6) /* 0.479920233 */, 17 }, + /* 3973 */ { MAD_F(0x07ae69c6) /* 0.480081341 */, 17 }, + /* 3974 */ { MAD_F(0x07af12b8) /* 0.480242463 */, 17 }, + /* 3975 */ { MAD_F(0x07afbbaf) /* 0.480403598 */, 17 }, + /* 3976 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 17 }, + /* 3977 */ { MAD_F(0x07b10da6) /* 0.480725908 */, 17 }, + /* 3978 */ { MAD_F(0x07b1b6a7) /* 0.480887083 */, 17 }, + /* 3979 */ { MAD_F(0x07b25fac) /* 0.481048272 */, 17 }, + /* 3980 */ { MAD_F(0x07b308b5) /* 0.481209475 */, 17 }, + /* 3981 */ { MAD_F(0x07b3b1c1) /* 0.481370691 */, 17 }, + /* 3982 */ { MAD_F(0x07b45ad0) /* 0.481531920 */, 17 }, + /* 3983 */ { MAD_F(0x07b503e4) /* 0.481693163 */, 17 }, + + /* 3984 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 17 }, + /* 3985 */ { MAD_F(0x07b65615) /* 0.482015690 */, 17 }, + /* 3986 */ { MAD_F(0x07b6ff33) /* 0.482176973 */, 17 }, + /* 3987 */ { MAD_F(0x07b7a855) /* 0.482338270 */, 17 }, + /* 3988 */ { MAD_F(0x07b8517b) /* 0.482499580 */, 17 }, + /* 3989 */ { MAD_F(0x07b8faa4) /* 0.482660904 */, 17 }, + /* 3990 */ { MAD_F(0x07b9a3d0) /* 0.482822242 */, 17 }, + /* 3991 */ { MAD_F(0x07ba4d01) /* 0.482983592 */, 17 }, + /* 3992 */ { MAD_F(0x07baf635) /* 0.483144957 */, 17 }, + /* 3993 */ { MAD_F(0x07bb9f6c) /* 0.483306335 */, 17 }, + /* 3994 */ { MAD_F(0x07bc48a7) /* 0.483467726 */, 17 }, + /* 3995 */ { MAD_F(0x07bcf1e6) /* 0.483629131 */, 17 }, + /* 3996 */ { MAD_F(0x07bd9b28) /* 0.483790549 */, 17 }, + /* 3997 */ { MAD_F(0x07be446e) /* 0.483951980 */, 17 }, + /* 3998 */ { MAD_F(0x07beedb8) /* 0.484113426 */, 17 }, + /* 3999 */ { MAD_F(0x07bf9705) /* 0.484274884 */, 17 }, + + /* 4000 */ { MAD_F(0x07c04056) /* 0.484436356 */, 17 }, + /* 4001 */ { MAD_F(0x07c0e9aa) /* 0.484597842 */, 17 }, + /* 4002 */ { MAD_F(0x07c19302) /* 0.484759341 */, 17 }, + /* 4003 */ { MAD_F(0x07c23c5e) /* 0.484920853 */, 17 }, + /* 4004 */ { MAD_F(0x07c2e5bd) /* 0.485082379 */, 17 }, + /* 4005 */ { MAD_F(0x07c38f20) /* 0.485243918 */, 17 }, + /* 4006 */ { MAD_F(0x07c43887) /* 0.485405471 */, 17 }, + /* 4007 */ { MAD_F(0x07c4e1f1) /* 0.485567037 */, 17 }, + /* 4008 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 17 }, + /* 4009 */ { MAD_F(0x07c634d0) /* 0.485890210 */, 17 }, + /* 4010 */ { MAD_F(0x07c6de45) /* 0.486051817 */, 17 }, + /* 4011 */ { MAD_F(0x07c787bd) /* 0.486213436 */, 17 }, + /* 4012 */ { MAD_F(0x07c83139) /* 0.486375070 */, 17 }, + /* 4013 */ { MAD_F(0x07c8dab9) /* 0.486536717 */, 17 }, + /* 4014 */ { MAD_F(0x07c9843c) /* 0.486698377 */, 17 }, + /* 4015 */ { MAD_F(0x07ca2dc3) /* 0.486860051 */, 17 }, + + /* 4016 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 17 }, + /* 4017 */ { MAD_F(0x07cb80dc) /* 0.487183438 */, 17 }, + /* 4018 */ { MAD_F(0x07cc2a6e) /* 0.487345152 */, 17 }, + /* 4019 */ { MAD_F(0x07ccd403) /* 0.487506879 */, 17 }, + /* 4020 */ { MAD_F(0x07cd7d9c) /* 0.487668620 */, 17 }, + /* 4021 */ { MAD_F(0x07ce2739) /* 0.487830374 */, 17 }, + /* 4022 */ { MAD_F(0x07ced0d9) /* 0.487992142 */, 17 }, + /* 4023 */ { MAD_F(0x07cf7a7d) /* 0.488153923 */, 17 }, + /* 4024 */ { MAD_F(0x07d02424) /* 0.488315717 */, 17 }, + /* 4025 */ { MAD_F(0x07d0cdcf) /* 0.488477525 */, 17 }, + /* 4026 */ { MAD_F(0x07d1777e) /* 0.488639346 */, 17 }, + /* 4027 */ { MAD_F(0x07d22130) /* 0.488801181 */, 17 }, + /* 4028 */ { MAD_F(0x07d2cae5) /* 0.488963029 */, 17 }, + /* 4029 */ { MAD_F(0x07d3749f) /* 0.489124890 */, 17 }, + /* 4030 */ { MAD_F(0x07d41e5c) /* 0.489286765 */, 17 }, + /* 4031 */ { MAD_F(0x07d4c81c) /* 0.489448653 */, 17 }, + + /* 4032 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 17 }, + /* 4033 */ { MAD_F(0x07d61ba8) /* 0.489772470 */, 17 }, + /* 4034 */ { MAD_F(0x07d6c573) /* 0.489934398 */, 17 }, + /* 4035 */ { MAD_F(0x07d76f42) /* 0.490096340 */, 17 }, + /* 4036 */ { MAD_F(0x07d81915) /* 0.490258295 */, 17 }, + /* 4037 */ { MAD_F(0x07d8c2eb) /* 0.490420263 */, 17 }, + /* 4038 */ { MAD_F(0x07d96cc4) /* 0.490582245 */, 17 }, + /* 4039 */ { MAD_F(0x07da16a2) /* 0.490744240 */, 17 }, + /* 4040 */ { MAD_F(0x07dac083) /* 0.490906249 */, 17 }, + /* 4041 */ { MAD_F(0x07db6a67) /* 0.491068271 */, 17 }, + /* 4042 */ { MAD_F(0x07dc144f) /* 0.491230306 */, 17 }, + /* 4043 */ { MAD_F(0x07dcbe3b) /* 0.491392355 */, 17 }, + /* 4044 */ { MAD_F(0x07dd682a) /* 0.491554417 */, 17 }, + /* 4045 */ { MAD_F(0x07de121d) /* 0.491716492 */, 17 }, + /* 4046 */ { MAD_F(0x07debc13) /* 0.491878581 */, 17 }, + /* 4047 */ { MAD_F(0x07df660d) /* 0.492040683 */, 17 }, + + /* 4048 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 17 }, + /* 4049 */ { MAD_F(0x07e0ba0c) /* 0.492364928 */, 17 }, + /* 4050 */ { MAD_F(0x07e16410) /* 0.492527070 */, 17 }, + /* 4051 */ { MAD_F(0x07e20e19) /* 0.492689225 */, 17 }, + /* 4052 */ { MAD_F(0x07e2b824) /* 0.492851394 */, 17 }, + /* 4053 */ { MAD_F(0x07e36234) /* 0.493013576 */, 17 }, + /* 4054 */ { MAD_F(0x07e40c47) /* 0.493175772 */, 17 }, + /* 4055 */ { MAD_F(0x07e4b65e) /* 0.493337981 */, 17 }, + /* 4056 */ { MAD_F(0x07e56078) /* 0.493500203 */, 17 }, + /* 4057 */ { MAD_F(0x07e60a95) /* 0.493662438 */, 17 }, + /* 4058 */ { MAD_F(0x07e6b4b7) /* 0.493824687 */, 17 }, + /* 4059 */ { MAD_F(0x07e75edc) /* 0.493986949 */, 17 }, + /* 4060 */ { MAD_F(0x07e80904) /* 0.494149225 */, 17 }, + /* 4061 */ { MAD_F(0x07e8b330) /* 0.494311514 */, 17 }, + /* 4062 */ { MAD_F(0x07e95d60) /* 0.494473816 */, 17 }, + /* 4063 */ { MAD_F(0x07ea0793) /* 0.494636131 */, 17 }, + + /* 4064 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 17 }, + /* 4065 */ { MAD_F(0x07eb5c04) /* 0.494960802 */, 17 }, + /* 4066 */ { MAD_F(0x07ec0642) /* 0.495123158 */, 17 }, + /* 4067 */ { MAD_F(0x07ecb084) /* 0.495285526 */, 17 }, + /* 4068 */ { MAD_F(0x07ed5ac9) /* 0.495447908 */, 17 }, + /* 4069 */ { MAD_F(0x07ee0512) /* 0.495610304 */, 17 }, + /* 4070 */ { MAD_F(0x07eeaf5e) /* 0.495772712 */, 17 }, + /* 4071 */ { MAD_F(0x07ef59ae) /* 0.495935134 */, 17 }, + /* 4072 */ { MAD_F(0x07f00401) /* 0.496097570 */, 17 }, + /* 4073 */ { MAD_F(0x07f0ae58) /* 0.496260018 */, 17 }, + /* 4074 */ { MAD_F(0x07f158b3) /* 0.496422480 */, 17 }, + /* 4075 */ { MAD_F(0x07f20311) /* 0.496584955 */, 17 }, + /* 4076 */ { MAD_F(0x07f2ad72) /* 0.496747444 */, 17 }, + /* 4077 */ { MAD_F(0x07f357d8) /* 0.496909945 */, 17 }, + /* 4078 */ { MAD_F(0x07f40240) /* 0.497072460 */, 17 }, + /* 4079 */ { MAD_F(0x07f4acad) /* 0.497234989 */, 17 }, + + /* 4080 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 17 }, + /* 4081 */ { MAD_F(0x07f60190) /* 0.497560085 */, 17 }, + /* 4082 */ { MAD_F(0x07f6ac07) /* 0.497722653 */, 17 }, + /* 4083 */ { MAD_F(0x07f75682) /* 0.497885235 */, 17 }, + /* 4084 */ { MAD_F(0x07f80100) /* 0.498047829 */, 17 }, + /* 4085 */ { MAD_F(0x07f8ab82) /* 0.498210437 */, 17 }, + /* 4086 */ { MAD_F(0x07f95607) /* 0.498373058 */, 17 }, + /* 4087 */ { MAD_F(0x07fa0090) /* 0.498535693 */, 17 }, + /* 4088 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 17 }, + /* 4089 */ { MAD_F(0x07fb55ac) /* 0.498861002 */, 17 }, + /* 4090 */ { MAD_F(0x07fc0040) /* 0.499023676 */, 17 }, + /* 4091 */ { MAD_F(0x07fcaad7) /* 0.499186364 */, 17 }, + /* 4092 */ { MAD_F(0x07fd5572) /* 0.499349064 */, 17 }, + /* 4093 */ { MAD_F(0x07fe0010) /* 0.499511778 */, 17 }, + /* 4094 */ { MAD_F(0x07feaab2) /* 0.499674506 */, 17 }, + /* 4095 */ { MAD_F(0x07ff5557) /* 0.499837246 */, 17 }, + + /* 4096 */ { MAD_F(0x04000000) /* 0.250000000 */, 18 }, + /* 4097 */ { MAD_F(0x04005556) /* 0.250081384 */, 18 }, + /* 4098 */ { MAD_F(0x0400aaae) /* 0.250162774 */, 18 }, + /* 4099 */ { MAD_F(0x04010008) /* 0.250244170 */, 18 }, + /* 4100 */ { MAD_F(0x04015563) /* 0.250325574 */, 18 }, + /* 4101 */ { MAD_F(0x0401aac1) /* 0.250406984 */, 18 }, + /* 4102 */ { MAD_F(0x04020020) /* 0.250488400 */, 18 }, + /* 4103 */ { MAD_F(0x04025581) /* 0.250569824 */, 18 }, + /* 4104 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 18 }, + /* 4105 */ { MAD_F(0x04030048) /* 0.250732690 */, 18 }, + /* 4106 */ { MAD_F(0x040355ae) /* 0.250814133 */, 18 }, + /* 4107 */ { MAD_F(0x0403ab16) /* 0.250895583 */, 18 }, + /* 4108 */ { MAD_F(0x04040080) /* 0.250977039 */, 18 }, + /* 4109 */ { MAD_F(0x040455eb) /* 0.251058502 */, 18 }, + /* 4110 */ { MAD_F(0x0404ab59) /* 0.251139971 */, 18 }, + /* 4111 */ { MAD_F(0x040500c8) /* 0.251221448 */, 18 }, + + /* 4112 */ { MAD_F(0x04055638) /* 0.251302930 */, 18 }, + /* 4113 */ { MAD_F(0x0405abab) /* 0.251384420 */, 18 }, + /* 4114 */ { MAD_F(0x0406011f) /* 0.251465916 */, 18 }, + /* 4115 */ { MAD_F(0x04065696) /* 0.251547418 */, 18 }, + /* 4116 */ { MAD_F(0x0406ac0e) /* 0.251628927 */, 18 }, + /* 4117 */ { MAD_F(0x04070187) /* 0.251710443 */, 18 }, + /* 4118 */ { MAD_F(0x04075703) /* 0.251791965 */, 18 }, + /* 4119 */ { MAD_F(0x0407ac80) /* 0.251873494 */, 18 }, + /* 4120 */ { MAD_F(0x040801ff) /* 0.251955030 */, 18 }, + /* 4121 */ { MAD_F(0x04085780) /* 0.252036572 */, 18 }, + /* 4122 */ { MAD_F(0x0408ad02) /* 0.252118121 */, 18 }, + /* 4123 */ { MAD_F(0x04090287) /* 0.252199676 */, 18 }, + /* 4124 */ { MAD_F(0x0409580d) /* 0.252281238 */, 18 }, + /* 4125 */ { MAD_F(0x0409ad95) /* 0.252362807 */, 18 }, + /* 4126 */ { MAD_F(0x040a031e) /* 0.252444382 */, 18 }, + /* 4127 */ { MAD_F(0x040a58aa) /* 0.252525963 */, 18 }, + + /* 4128 */ { MAD_F(0x040aae37) /* 0.252607552 */, 18 }, + /* 4129 */ { MAD_F(0x040b03c6) /* 0.252689147 */, 18 }, + /* 4130 */ { MAD_F(0x040b5957) /* 0.252770748 */, 18 }, + /* 4131 */ { MAD_F(0x040baee9) /* 0.252852356 */, 18 }, + /* 4132 */ { MAD_F(0x040c047e) /* 0.252933971 */, 18 }, + /* 4133 */ { MAD_F(0x040c5a14) /* 0.253015592 */, 18 }, + /* 4134 */ { MAD_F(0x040cafab) /* 0.253097220 */, 18 }, + /* 4135 */ { MAD_F(0x040d0545) /* 0.253178854 */, 18 }, + /* 4136 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 18 }, + /* 4137 */ { MAD_F(0x040db07d) /* 0.253342143 */, 18 }, + /* 4138 */ { MAD_F(0x040e061c) /* 0.253423797 */, 18 }, + /* 4139 */ { MAD_F(0x040e5bbd) /* 0.253505457 */, 18 }, + /* 4140 */ { MAD_F(0x040eb15f) /* 0.253587125 */, 18 }, + /* 4141 */ { MAD_F(0x040f0703) /* 0.253668799 */, 18 }, + /* 4142 */ { MAD_F(0x040f5ca9) /* 0.253750479 */, 18 }, + /* 4143 */ { MAD_F(0x040fb251) /* 0.253832166 */, 18 }, + + /* 4144 */ { MAD_F(0x041007fa) /* 0.253913860 */, 18 }, + /* 4145 */ { MAD_F(0x04105da6) /* 0.253995560 */, 18 }, + /* 4146 */ { MAD_F(0x0410b353) /* 0.254077266 */, 18 }, + /* 4147 */ { MAD_F(0x04110901) /* 0.254158980 */, 18 }, + /* 4148 */ { MAD_F(0x04115eb2) /* 0.254240700 */, 18 }, + /* 4149 */ { MAD_F(0x0411b464) /* 0.254322426 */, 18 }, + /* 4150 */ { MAD_F(0x04120a18) /* 0.254404159 */, 18 }, + /* 4151 */ { MAD_F(0x04125fce) /* 0.254485899 */, 18 }, + /* 4152 */ { MAD_F(0x0412b586) /* 0.254567645 */, 18 }, + /* 4153 */ { MAD_F(0x04130b3f) /* 0.254649397 */, 18 }, + /* 4154 */ { MAD_F(0x041360fa) /* 0.254731157 */, 18 }, + /* 4155 */ { MAD_F(0x0413b6b7) /* 0.254812922 */, 18 }, + /* 4156 */ { MAD_F(0x04140c75) /* 0.254894695 */, 18 }, + /* 4157 */ { MAD_F(0x04146236) /* 0.254976474 */, 18 }, + /* 4158 */ { MAD_F(0x0414b7f8) /* 0.255058259 */, 18 }, + /* 4159 */ { MAD_F(0x04150dbc) /* 0.255140051 */, 18 }, + + /* 4160 */ { MAD_F(0x04156381) /* 0.255221850 */, 18 }, + /* 4161 */ { MAD_F(0x0415b949) /* 0.255303655 */, 18 }, + /* 4162 */ { MAD_F(0x04160f12) /* 0.255385467 */, 18 }, + /* 4163 */ { MAD_F(0x041664dd) /* 0.255467285 */, 18 }, + /* 4164 */ { MAD_F(0x0416baaa) /* 0.255549110 */, 18 }, + /* 4165 */ { MAD_F(0x04171078) /* 0.255630941 */, 18 }, + /* 4166 */ { MAD_F(0x04176648) /* 0.255712779 */, 18 }, + /* 4167 */ { MAD_F(0x0417bc1a) /* 0.255794624 */, 18 }, + /* 4168 */ { MAD_F(0x041811ee) /* 0.255876475 */, 18 }, + /* 4169 */ { MAD_F(0x041867c3) /* 0.255958332 */, 18 }, + /* 4170 */ { MAD_F(0x0418bd9b) /* 0.256040196 */, 18 }, + /* 4171 */ { MAD_F(0x04191374) /* 0.256122067 */, 18 }, + /* 4172 */ { MAD_F(0x0419694e) /* 0.256203944 */, 18 }, + /* 4173 */ { MAD_F(0x0419bf2b) /* 0.256285828 */, 18 }, + /* 4174 */ { MAD_F(0x041a1509) /* 0.256367718 */, 18 }, + /* 4175 */ { MAD_F(0x041a6ae9) /* 0.256449615 */, 18 }, + + /* 4176 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 18 }, + /* 4177 */ { MAD_F(0x041b16ae) /* 0.256613428 */, 18 }, + /* 4178 */ { MAD_F(0x041b6c94) /* 0.256695344 */, 18 }, + /* 4179 */ { MAD_F(0x041bc27b) /* 0.256777267 */, 18 }, + /* 4180 */ { MAD_F(0x041c1863) /* 0.256859197 */, 18 }, + /* 4181 */ { MAD_F(0x041c6e4e) /* 0.256941133 */, 18 }, + /* 4182 */ { MAD_F(0x041cc43a) /* 0.257023076 */, 18 }, + /* 4183 */ { MAD_F(0x041d1a28) /* 0.257105025 */, 18 }, + /* 4184 */ { MAD_F(0x041d7018) /* 0.257186980 */, 18 }, + /* 4185 */ { MAD_F(0x041dc60a) /* 0.257268942 */, 18 }, + /* 4186 */ { MAD_F(0x041e1bfd) /* 0.257350911 */, 18 }, + /* 4187 */ { MAD_F(0x041e71f2) /* 0.257432886 */, 18 }, + /* 4188 */ { MAD_F(0x041ec7e9) /* 0.257514868 */, 18 }, + /* 4189 */ { MAD_F(0x041f1de1) /* 0.257596856 */, 18 }, + /* 4190 */ { MAD_F(0x041f73dc) /* 0.257678851 */, 18 }, + /* 4191 */ { MAD_F(0x041fc9d8) /* 0.257760852 */, 18 }, + + /* 4192 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 18 }, + /* 4193 */ { MAD_F(0x042075d5) /* 0.257924875 */, 18 }, + /* 4194 */ { MAD_F(0x0420cbd6) /* 0.258006895 */, 18 }, + /* 4195 */ { MAD_F(0x042121d9) /* 0.258088923 */, 18 }, + /* 4196 */ { MAD_F(0x042177de) /* 0.258170957 */, 18 }, + /* 4197 */ { MAD_F(0x0421cde5) /* 0.258252997 */, 18 }, + /* 4198 */ { MAD_F(0x042223ed) /* 0.258335044 */, 18 }, + /* 4199 */ { MAD_F(0x042279f7) /* 0.258417097 */, 18 }, + /* 4200 */ { MAD_F(0x0422d003) /* 0.258499157 */, 18 }, + /* 4201 */ { MAD_F(0x04232611) /* 0.258581224 */, 18 }, + /* 4202 */ { MAD_F(0x04237c20) /* 0.258663297 */, 18 }, + /* 4203 */ { MAD_F(0x0423d231) /* 0.258745376 */, 18 }, + /* 4204 */ { MAD_F(0x04242844) /* 0.258827462 */, 18 }, + /* 4205 */ { MAD_F(0x04247e58) /* 0.258909555 */, 18 }, + /* 4206 */ { MAD_F(0x0424d46e) /* 0.258991654 */, 18 }, + /* 4207 */ { MAD_F(0x04252a87) /* 0.259073760 */, 18 }, + + /* 4208 */ { MAD_F(0x042580a0) /* 0.259155872 */, 18 }, + /* 4209 */ { MAD_F(0x0425d6bc) /* 0.259237990 */, 18 }, + /* 4210 */ { MAD_F(0x04262cd9) /* 0.259320115 */, 18 }, + /* 4211 */ { MAD_F(0x042682f8) /* 0.259402247 */, 18 }, + /* 4212 */ { MAD_F(0x0426d919) /* 0.259484385 */, 18 }, + /* 4213 */ { MAD_F(0x04272f3b) /* 0.259566529 */, 18 }, + /* 4214 */ { MAD_F(0x04278560) /* 0.259648680 */, 18 }, + /* 4215 */ { MAD_F(0x0427db86) /* 0.259730838 */, 18 }, + /* 4216 */ { MAD_F(0x042831ad) /* 0.259813002 */, 18 }, + /* 4217 */ { MAD_F(0x042887d7) /* 0.259895173 */, 18 }, + /* 4218 */ { MAD_F(0x0428de02) /* 0.259977350 */, 18 }, + /* 4219 */ { MAD_F(0x0429342f) /* 0.260059533 */, 18 }, + /* 4220 */ { MAD_F(0x04298a5e) /* 0.260141723 */, 18 }, + /* 4221 */ { MAD_F(0x0429e08e) /* 0.260223920 */, 18 }, + /* 4222 */ { MAD_F(0x042a36c0) /* 0.260306123 */, 18 }, + /* 4223 */ { MAD_F(0x042a8cf4) /* 0.260388332 */, 18 }, + + /* 4224 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 18 }, + /* 4225 */ { MAD_F(0x042b3962) /* 0.260552771 */, 18 }, + /* 4226 */ { MAD_F(0x042b8f9b) /* 0.260635000 */, 18 }, + /* 4227 */ { MAD_F(0x042be5d6) /* 0.260717235 */, 18 }, + /* 4228 */ { MAD_F(0x042c3c12) /* 0.260799477 */, 18 }, + /* 4229 */ { MAD_F(0x042c9251) /* 0.260881725 */, 18 }, + /* 4230 */ { MAD_F(0x042ce891) /* 0.260963980 */, 18 }, + /* 4231 */ { MAD_F(0x042d3ed3) /* 0.261046242 */, 18 }, + /* 4232 */ { MAD_F(0x042d9516) /* 0.261128510 */, 18 }, + /* 4233 */ { MAD_F(0x042deb5c) /* 0.261210784 */, 18 }, + /* 4234 */ { MAD_F(0x042e41a3) /* 0.261293065 */, 18 }, + /* 4235 */ { MAD_F(0x042e97ec) /* 0.261375352 */, 18 }, + /* 4236 */ { MAD_F(0x042eee36) /* 0.261457646 */, 18 }, + /* 4237 */ { MAD_F(0x042f4482) /* 0.261539946 */, 18 }, + /* 4238 */ { MAD_F(0x042f9ad1) /* 0.261622253 */, 18 }, + /* 4239 */ { MAD_F(0x042ff120) /* 0.261704566 */, 18 }, + + /* 4240 */ { MAD_F(0x04304772) /* 0.261786886 */, 18 }, + /* 4241 */ { MAD_F(0x04309dc5) /* 0.261869212 */, 18 }, + /* 4242 */ { MAD_F(0x0430f41a) /* 0.261951545 */, 18 }, + /* 4243 */ { MAD_F(0x04314a71) /* 0.262033884 */, 18 }, + /* 4244 */ { MAD_F(0x0431a0c9) /* 0.262116229 */, 18 }, + /* 4245 */ { MAD_F(0x0431f723) /* 0.262198581 */, 18 }, + /* 4246 */ { MAD_F(0x04324d7f) /* 0.262280940 */, 18 }, + /* 4247 */ { MAD_F(0x0432a3dd) /* 0.262363305 */, 18 }, + /* 4248 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 18 }, + /* 4249 */ { MAD_F(0x0433509e) /* 0.262528054 */, 18 }, + /* 4250 */ { MAD_F(0x0433a701) /* 0.262610438 */, 18 }, + /* 4251 */ { MAD_F(0x0433fd65) /* 0.262692829 */, 18 }, + /* 4252 */ { MAD_F(0x043453cc) /* 0.262775227 */, 18 }, + /* 4253 */ { MAD_F(0x0434aa34) /* 0.262857630 */, 18 }, + /* 4254 */ { MAD_F(0x0435009d) /* 0.262940040 */, 18 }, + /* 4255 */ { MAD_F(0x04355709) /* 0.263022457 */, 18 }, + + /* 4256 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 18 }, + /* 4257 */ { MAD_F(0x043603e5) /* 0.263187310 */, 18 }, + /* 4258 */ { MAD_F(0x04365a56) /* 0.263269746 */, 18 }, + /* 4259 */ { MAD_F(0x0436b0c9) /* 0.263352188 */, 18 }, + /* 4260 */ { MAD_F(0x0437073d) /* 0.263434637 */, 18 }, + /* 4261 */ { MAD_F(0x04375db3) /* 0.263517093 */, 18 }, + /* 4262 */ { MAD_F(0x0437b42a) /* 0.263599554 */, 18 }, + /* 4263 */ { MAD_F(0x04380aa4) /* 0.263682023 */, 18 }, + /* 4264 */ { MAD_F(0x0438611f) /* 0.263764497 */, 18 }, + /* 4265 */ { MAD_F(0x0438b79c) /* 0.263846979 */, 18 }, + /* 4266 */ { MAD_F(0x04390e1a) /* 0.263929466 */, 18 }, + /* 4267 */ { MAD_F(0x0439649b) /* 0.264011960 */, 18 }, + /* 4268 */ { MAD_F(0x0439bb1d) /* 0.264094461 */, 18 }, + /* 4269 */ { MAD_F(0x043a11a1) /* 0.264176968 */, 18 }, + /* 4270 */ { MAD_F(0x043a6826) /* 0.264259481 */, 18 }, + /* 4271 */ { MAD_F(0x043abead) /* 0.264342001 */, 18 }, + + /* 4272 */ { MAD_F(0x043b1536) /* 0.264424527 */, 18 }, + /* 4273 */ { MAD_F(0x043b6bc1) /* 0.264507060 */, 18 }, + /* 4274 */ { MAD_F(0x043bc24d) /* 0.264589599 */, 18 }, + /* 4275 */ { MAD_F(0x043c18dc) /* 0.264672145 */, 18 }, + /* 4276 */ { MAD_F(0x043c6f6c) /* 0.264754697 */, 18 }, + /* 4277 */ { MAD_F(0x043cc5fd) /* 0.264837255 */, 18 }, + /* 4278 */ { MAD_F(0x043d1c91) /* 0.264919820 */, 18 }, + /* 4279 */ { MAD_F(0x043d7326) /* 0.265002392 */, 18 }, + /* 4280 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 18 }, + /* 4281 */ { MAD_F(0x043e2055) /* 0.265167554 */, 18 }, + /* 4282 */ { MAD_F(0x043e76ef) /* 0.265250144 */, 18 }, + /* 4283 */ { MAD_F(0x043ecd8b) /* 0.265332741 */, 18 }, + /* 4284 */ { MAD_F(0x043f2429) /* 0.265415345 */, 18 }, + /* 4285 */ { MAD_F(0x043f7ac8) /* 0.265497955 */, 18 }, + /* 4286 */ { MAD_F(0x043fd169) /* 0.265580571 */, 18 }, + /* 4287 */ { MAD_F(0x0440280c) /* 0.265663194 */, 18 }, + + /* 4288 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 18 }, + /* 4289 */ { MAD_F(0x0440d557) /* 0.265828459 */, 18 }, + /* 4290 */ { MAD_F(0x04412bff) /* 0.265911101 */, 18 }, + /* 4291 */ { MAD_F(0x044182a9) /* 0.265993749 */, 18 }, + /* 4292 */ { MAD_F(0x0441d955) /* 0.266076404 */, 18 }, + /* 4293 */ { MAD_F(0x04423002) /* 0.266159065 */, 18 }, + /* 4294 */ { MAD_F(0x044286b1) /* 0.266241733 */, 18 }, + /* 4295 */ { MAD_F(0x0442dd61) /* 0.266324407 */, 18 }, + /* 4296 */ { MAD_F(0x04433414) /* 0.266407088 */, 18 }, + /* 4297 */ { MAD_F(0x04438ac8) /* 0.266489775 */, 18 }, + /* 4298 */ { MAD_F(0x0443e17e) /* 0.266572468 */, 18 }, + /* 4299 */ { MAD_F(0x04443835) /* 0.266655168 */, 18 }, + /* 4300 */ { MAD_F(0x04448eef) /* 0.266737874 */, 18 }, + /* 4301 */ { MAD_F(0x0444e5aa) /* 0.266820587 */, 18 }, + /* 4302 */ { MAD_F(0x04453c66) /* 0.266903306 */, 18 }, + /* 4303 */ { MAD_F(0x04459325) /* 0.266986031 */, 18 }, + + /* 4304 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 18 }, + /* 4305 */ { MAD_F(0x044640a7) /* 0.267151501 */, 18 }, + /* 4306 */ { MAD_F(0x0446976a) /* 0.267234246 */, 18 }, + /* 4307 */ { MAD_F(0x0446ee30) /* 0.267316997 */, 18 }, + /* 4308 */ { MAD_F(0x044744f7) /* 0.267399755 */, 18 }, + /* 4309 */ { MAD_F(0x04479bc0) /* 0.267482518 */, 18 }, + /* 4310 */ { MAD_F(0x0447f28a) /* 0.267565289 */, 18 }, + /* 4311 */ { MAD_F(0x04484956) /* 0.267648065 */, 18 }, + /* 4312 */ { MAD_F(0x0448a024) /* 0.267730848 */, 18 }, + /* 4313 */ { MAD_F(0x0448f6f4) /* 0.267813638 */, 18 }, + /* 4314 */ { MAD_F(0x04494dc5) /* 0.267896434 */, 18 }, + /* 4315 */ { MAD_F(0x0449a498) /* 0.267979236 */, 18 }, + /* 4316 */ { MAD_F(0x0449fb6d) /* 0.268062045 */, 18 }, + /* 4317 */ { MAD_F(0x044a5243) /* 0.268144860 */, 18 }, + /* 4318 */ { MAD_F(0x044aa91c) /* 0.268227681 */, 18 }, + /* 4319 */ { MAD_F(0x044afff6) /* 0.268310509 */, 18 }, + + /* 4320 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 18 }, + /* 4321 */ { MAD_F(0x044badaf) /* 0.268476184 */, 18 }, + /* 4322 */ { MAD_F(0x044c048e) /* 0.268559031 */, 18 }, + /* 4323 */ { MAD_F(0x044c5b6f) /* 0.268641885 */, 18 }, + /* 4324 */ { MAD_F(0x044cb251) /* 0.268724744 */, 18 }, + /* 4325 */ { MAD_F(0x044d0935) /* 0.268807611 */, 18 }, + /* 4326 */ { MAD_F(0x044d601b) /* 0.268890483 */, 18 }, + /* 4327 */ { MAD_F(0x044db703) /* 0.268973362 */, 18 }, + /* 4328 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 18 }, + /* 4329 */ { MAD_F(0x044e64d7) /* 0.269139139 */, 18 }, + /* 4330 */ { MAD_F(0x044ebbc4) /* 0.269222037 */, 18 }, + /* 4331 */ { MAD_F(0x044f12b3) /* 0.269304942 */, 18 }, + /* 4332 */ { MAD_F(0x044f69a3) /* 0.269387853 */, 18 }, + /* 4333 */ { MAD_F(0x044fc095) /* 0.269470770 */, 18 }, + /* 4334 */ { MAD_F(0x04501788) /* 0.269553694 */, 18 }, + /* 4335 */ { MAD_F(0x04506e7e) /* 0.269636624 */, 18 }, + + /* 4336 */ { MAD_F(0x0450c575) /* 0.269719560 */, 18 }, + /* 4337 */ { MAD_F(0x04511c6e) /* 0.269802503 */, 18 }, + /* 4338 */ { MAD_F(0x04517368) /* 0.269885452 */, 18 }, + /* 4339 */ { MAD_F(0x0451ca64) /* 0.269968408 */, 18 }, + /* 4340 */ { MAD_F(0x04522162) /* 0.270051370 */, 18 }, + /* 4341 */ { MAD_F(0x04527862) /* 0.270134338 */, 18 }, + /* 4342 */ { MAD_F(0x0452cf63) /* 0.270217312 */, 18 }, + /* 4343 */ { MAD_F(0x04532666) /* 0.270300293 */, 18 }, + /* 4344 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 18 }, + /* 4345 */ { MAD_F(0x0453d472) /* 0.270466275 */, 18 }, + /* 4346 */ { MAD_F(0x04542b7a) /* 0.270549275 */, 18 }, + /* 4347 */ { MAD_F(0x04548284) /* 0.270632281 */, 18 }, + /* 4348 */ { MAD_F(0x0454d98f) /* 0.270715294 */, 18 }, + /* 4349 */ { MAD_F(0x0455309c) /* 0.270798313 */, 18 }, + /* 4350 */ { MAD_F(0x045587ab) /* 0.270881339 */, 18 }, + /* 4351 */ { MAD_F(0x0455debc) /* 0.270964371 */, 18 }, + + /* 4352 */ { MAD_F(0x045635cf) /* 0.271047409 */, 18 }, + /* 4353 */ { MAD_F(0x04568ce3) /* 0.271130454 */, 18 }, + /* 4354 */ { MAD_F(0x0456e3f9) /* 0.271213505 */, 18 }, + /* 4355 */ { MAD_F(0x04573b10) /* 0.271296562 */, 18 }, + /* 4356 */ { MAD_F(0x04579229) /* 0.271379626 */, 18 }, + /* 4357 */ { MAD_F(0x0457e944) /* 0.271462696 */, 18 }, + /* 4358 */ { MAD_F(0x04584061) /* 0.271545772 */, 18 }, + /* 4359 */ { MAD_F(0x0458977f) /* 0.271628855 */, 18 }, + /* 4360 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 18 }, + /* 4361 */ { MAD_F(0x045945c1) /* 0.271795040 */, 18 }, + /* 4362 */ { MAD_F(0x04599ce5) /* 0.271878142 */, 18 }, + /* 4363 */ { MAD_F(0x0459f40a) /* 0.271961250 */, 18 }, + /* 4364 */ { MAD_F(0x045a4b31) /* 0.272044365 */, 18 }, + /* 4365 */ { MAD_F(0x045aa259) /* 0.272127486 */, 18 }, + /* 4366 */ { MAD_F(0x045af984) /* 0.272210613 */, 18 }, + /* 4367 */ { MAD_F(0x045b50b0) /* 0.272293746 */, 18 }, + + /* 4368 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 18 }, + /* 4369 */ { MAD_F(0x045bff0d) /* 0.272460033 */, 18 }, + /* 4370 */ { MAD_F(0x045c563e) /* 0.272543185 */, 18 }, + /* 4371 */ { MAD_F(0x045cad71) /* 0.272626344 */, 18 }, + /* 4372 */ { MAD_F(0x045d04a5) /* 0.272709510 */, 18 }, + /* 4373 */ { MAD_F(0x045d5bdc) /* 0.272792681 */, 18 }, + /* 4374 */ { MAD_F(0x045db313) /* 0.272875859 */, 18 }, + /* 4375 */ { MAD_F(0x045e0a4d) /* 0.272959044 */, 18 }, + /* 4376 */ { MAD_F(0x045e6188) /* 0.273042234 */, 18 }, + /* 4377 */ { MAD_F(0x045eb8c5) /* 0.273125431 */, 18 }, + /* 4378 */ { MAD_F(0x045f1004) /* 0.273208635 */, 18 }, + /* 4379 */ { MAD_F(0x045f6745) /* 0.273291844 */, 18 }, + /* 4380 */ { MAD_F(0x045fbe87) /* 0.273375060 */, 18 }, + /* 4381 */ { MAD_F(0x046015cb) /* 0.273458283 */, 18 }, + /* 4382 */ { MAD_F(0x04606d10) /* 0.273541511 */, 18 }, + /* 4383 */ { MAD_F(0x0460c457) /* 0.273624747 */, 18 }, + + /* 4384 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 18 }, + /* 4385 */ { MAD_F(0x046172eb) /* 0.273791236 */, 18 }, + /* 4386 */ { MAD_F(0x0461ca37) /* 0.273874490 */, 18 }, + /* 4387 */ { MAD_F(0x04622185) /* 0.273957750 */, 18 }, + /* 4388 */ { MAD_F(0x046278d5) /* 0.274041017 */, 18 }, + /* 4389 */ { MAD_F(0x0462d026) /* 0.274124290 */, 18 }, + /* 4390 */ { MAD_F(0x0463277a) /* 0.274207569 */, 18 }, + /* 4391 */ { MAD_F(0x04637ece) /* 0.274290855 */, 18 }, + /* 4392 */ { MAD_F(0x0463d625) /* 0.274374147 */, 18 }, + /* 4393 */ { MAD_F(0x04642d7d) /* 0.274457445 */, 18 }, + /* 4394 */ { MAD_F(0x046484d7) /* 0.274540749 */, 18 }, + /* 4395 */ { MAD_F(0x0464dc33) /* 0.274624060 */, 18 }, + /* 4396 */ { MAD_F(0x04653390) /* 0.274707378 */, 18 }, + /* 4397 */ { MAD_F(0x04658aef) /* 0.274790701 */, 18 }, + /* 4398 */ { MAD_F(0x0465e250) /* 0.274874031 */, 18 }, + /* 4399 */ { MAD_F(0x046639b2) /* 0.274957367 */, 18 }, + + /* 4400 */ { MAD_F(0x04669116) /* 0.275040710 */, 18 }, + /* 4401 */ { MAD_F(0x0466e87c) /* 0.275124059 */, 18 }, + /* 4402 */ { MAD_F(0x04673fe3) /* 0.275207414 */, 18 }, + /* 4403 */ { MAD_F(0x0467974d) /* 0.275290775 */, 18 }, + /* 4404 */ { MAD_F(0x0467eeb7) /* 0.275374143 */, 18 }, + /* 4405 */ { MAD_F(0x04684624) /* 0.275457517 */, 18 }, + /* 4406 */ { MAD_F(0x04689d92) /* 0.275540897 */, 18 }, + /* 4407 */ { MAD_F(0x0468f502) /* 0.275624284 */, 18 }, + /* 4408 */ { MAD_F(0x04694c74) /* 0.275707677 */, 18 }, + /* 4409 */ { MAD_F(0x0469a3e7) /* 0.275791076 */, 18 }, + /* 4410 */ { MAD_F(0x0469fb5c) /* 0.275874482 */, 18 }, + /* 4411 */ { MAD_F(0x046a52d3) /* 0.275957894 */, 18 }, + /* 4412 */ { MAD_F(0x046aaa4b) /* 0.276041312 */, 18 }, + /* 4413 */ { MAD_F(0x046b01c5) /* 0.276124737 */, 18 }, + /* 4414 */ { MAD_F(0x046b5941) /* 0.276208167 */, 18 }, + /* 4415 */ { MAD_F(0x046bb0bf) /* 0.276291605 */, 18 }, + + /* 4416 */ { MAD_F(0x046c083e) /* 0.276375048 */, 18 }, + /* 4417 */ { MAD_F(0x046c5fbf) /* 0.276458498 */, 18 }, + /* 4418 */ { MAD_F(0x046cb741) /* 0.276541954 */, 18 }, + /* 4419 */ { MAD_F(0x046d0ec5) /* 0.276625416 */, 18 }, + /* 4420 */ { MAD_F(0x046d664b) /* 0.276708885 */, 18 }, + /* 4421 */ { MAD_F(0x046dbdd3) /* 0.276792360 */, 18 }, + /* 4422 */ { MAD_F(0x046e155c) /* 0.276875841 */, 18 }, + /* 4423 */ { MAD_F(0x046e6ce7) /* 0.276959328 */, 18 }, + /* 4424 */ { MAD_F(0x046ec474) /* 0.277042822 */, 18 }, + /* 4425 */ { MAD_F(0x046f1c02) /* 0.277126322 */, 18 }, + /* 4426 */ { MAD_F(0x046f7392) /* 0.277209829 */, 18 }, + /* 4427 */ { MAD_F(0x046fcb24) /* 0.277293341 */, 18 }, + /* 4428 */ { MAD_F(0x047022b8) /* 0.277376860 */, 18 }, + /* 4429 */ { MAD_F(0x04707a4d) /* 0.277460385 */, 18 }, + /* 4430 */ { MAD_F(0x0470d1e4) /* 0.277543917 */, 18 }, + /* 4431 */ { MAD_F(0x0471297c) /* 0.277627455 */, 18 }, + + /* 4432 */ { MAD_F(0x04718116) /* 0.277710999 */, 18 }, + /* 4433 */ { MAD_F(0x0471d8b2) /* 0.277794549 */, 18 }, + /* 4434 */ { MAD_F(0x04723050) /* 0.277878106 */, 18 }, + /* 4435 */ { MAD_F(0x047287ef) /* 0.277961669 */, 18 }, + /* 4436 */ { MAD_F(0x0472df90) /* 0.278045238 */, 18 }, + /* 4437 */ { MAD_F(0x04733733) /* 0.278128813 */, 18 }, + /* 4438 */ { MAD_F(0x04738ed7) /* 0.278212395 */, 18 }, + /* 4439 */ { MAD_F(0x0473e67d) /* 0.278295983 */, 18 }, + /* 4440 */ { MAD_F(0x04743e25) /* 0.278379578 */, 18 }, + /* 4441 */ { MAD_F(0x047495ce) /* 0.278463178 */, 18 }, + /* 4442 */ { MAD_F(0x0474ed79) /* 0.278546785 */, 18 }, + /* 4443 */ { MAD_F(0x04754526) /* 0.278630398 */, 18 }, + /* 4444 */ { MAD_F(0x04759cd4) /* 0.278714018 */, 18 }, + /* 4445 */ { MAD_F(0x0475f484) /* 0.278797643 */, 18 }, + /* 4446 */ { MAD_F(0x04764c36) /* 0.278881275 */, 18 }, + /* 4447 */ { MAD_F(0x0476a3ea) /* 0.278964914 */, 18 }, + + /* 4448 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 18 }, + /* 4449 */ { MAD_F(0x04775356) /* 0.279132209 */, 18 }, + /* 4450 */ { MAD_F(0x0477ab0e) /* 0.279215866 */, 18 }, + /* 4451 */ { MAD_F(0x047802c8) /* 0.279299529 */, 18 }, + /* 4452 */ { MAD_F(0x04785a84) /* 0.279383199 */, 18 }, + /* 4453 */ { MAD_F(0x0478b242) /* 0.279466875 */, 18 }, + /* 4454 */ { MAD_F(0x04790a01) /* 0.279550557 */, 18 }, + /* 4455 */ { MAD_F(0x047961c2) /* 0.279634245 */, 18 }, + /* 4456 */ { MAD_F(0x0479b984) /* 0.279717940 */, 18 }, + /* 4457 */ { MAD_F(0x047a1149) /* 0.279801641 */, 18 }, + /* 4458 */ { MAD_F(0x047a690f) /* 0.279885348 */, 18 }, + /* 4459 */ { MAD_F(0x047ac0d6) /* 0.279969061 */, 18 }, + /* 4460 */ { MAD_F(0x047b18a0) /* 0.280052781 */, 18 }, + /* 4461 */ { MAD_F(0x047b706b) /* 0.280136507 */, 18 }, + /* 4462 */ { MAD_F(0x047bc837) /* 0.280220239 */, 18 }, + /* 4463 */ { MAD_F(0x047c2006) /* 0.280303978 */, 18 }, + + /* 4464 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 18 }, + /* 4465 */ { MAD_F(0x047ccfa8) /* 0.280471473 */, 18 }, + /* 4466 */ { MAD_F(0x047d277b) /* 0.280555230 */, 18 }, + /* 4467 */ { MAD_F(0x047d7f50) /* 0.280638994 */, 18 }, + /* 4468 */ { MAD_F(0x047dd727) /* 0.280722764 */, 18 }, + /* 4469 */ { MAD_F(0x047e2eff) /* 0.280806540 */, 18 }, + /* 4470 */ { MAD_F(0x047e86d9) /* 0.280890322 */, 18 }, + /* 4471 */ { MAD_F(0x047edeb5) /* 0.280974110 */, 18 }, + /* 4472 */ { MAD_F(0x047f3693) /* 0.281057905 */, 18 }, + /* 4473 */ { MAD_F(0x047f8e72) /* 0.281141706 */, 18 }, + /* 4474 */ { MAD_F(0x047fe653) /* 0.281225513 */, 18 }, + /* 4475 */ { MAD_F(0x04803e35) /* 0.281309326 */, 18 }, + /* 4476 */ { MAD_F(0x04809619) /* 0.281393146 */, 18 }, + /* 4477 */ { MAD_F(0x0480edff) /* 0.281476972 */, 18 }, + /* 4478 */ { MAD_F(0x048145e7) /* 0.281560804 */, 18 }, + /* 4479 */ { MAD_F(0x04819dd0) /* 0.281644643 */, 18 }, + + /* 4480 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 18 }, + /* 4481 */ { MAD_F(0x04824da7) /* 0.281812338 */, 18 }, + /* 4482 */ { MAD_F(0x0482a595) /* 0.281896195 */, 18 }, + /* 4483 */ { MAD_F(0x0482fd85) /* 0.281980059 */, 18 }, + /* 4484 */ { MAD_F(0x04835577) /* 0.282063928 */, 18 }, + /* 4485 */ { MAD_F(0x0483ad6a) /* 0.282147804 */, 18 }, + /* 4486 */ { MAD_F(0x0484055f) /* 0.282231686 */, 18 }, + /* 4487 */ { MAD_F(0x04845d56) /* 0.282315574 */, 18 }, + /* 4488 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 18 }, + /* 4489 */ { MAD_F(0x04850d48) /* 0.282483370 */, 18 }, + /* 4490 */ { MAD_F(0x04856544) /* 0.282567277 */, 18 }, + /* 4491 */ { MAD_F(0x0485bd41) /* 0.282651190 */, 18 }, + /* 4492 */ { MAD_F(0x04861540) /* 0.282735109 */, 18 }, + /* 4493 */ { MAD_F(0x04866d40) /* 0.282819035 */, 18 }, + /* 4494 */ { MAD_F(0x0486c543) /* 0.282902967 */, 18 }, + /* 4495 */ { MAD_F(0x04871d47) /* 0.282986905 */, 18 }, + + /* 4496 */ { MAD_F(0x0487754c) /* 0.283070849 */, 18 }, + /* 4497 */ { MAD_F(0x0487cd54) /* 0.283154800 */, 18 }, + /* 4498 */ { MAD_F(0x0488255d) /* 0.283238757 */, 18 }, + /* 4499 */ { MAD_F(0x04887d67) /* 0.283322720 */, 18 }, + /* 4500 */ { MAD_F(0x0488d574) /* 0.283406689 */, 18 }, + /* 4501 */ { MAD_F(0x04892d82) /* 0.283490665 */, 18 }, + /* 4502 */ { MAD_F(0x04898591) /* 0.283574646 */, 18 }, + /* 4503 */ { MAD_F(0x0489dda3) /* 0.283658634 */, 18 }, + /* 4504 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 18 }, + /* 4505 */ { MAD_F(0x048a8dca) /* 0.283826629 */, 18 }, + /* 4506 */ { MAD_F(0x048ae5e1) /* 0.283910635 */, 18 }, + /* 4507 */ { MAD_F(0x048b3df9) /* 0.283994648 */, 18 }, + /* 4508 */ { MAD_F(0x048b9612) /* 0.284078667 */, 18 }, + /* 4509 */ { MAD_F(0x048bee2e) /* 0.284162692 */, 18 }, + /* 4510 */ { MAD_F(0x048c464b) /* 0.284246723 */, 18 }, + /* 4511 */ { MAD_F(0x048c9e69) /* 0.284330761 */, 18 }, + + /* 4512 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 18 }, + /* 4513 */ { MAD_F(0x048d4eac) /* 0.284498855 */, 18 }, + /* 4514 */ { MAD_F(0x048da6cf) /* 0.284582911 */, 18 }, + /* 4515 */ { MAD_F(0x048dfef5) /* 0.284666974 */, 18 }, + /* 4516 */ { MAD_F(0x048e571c) /* 0.284751042 */, 18 }, + /* 4517 */ { MAD_F(0x048eaf44) /* 0.284835117 */, 18 }, + /* 4518 */ { MAD_F(0x048f076f) /* 0.284919198 */, 18 }, + /* 4519 */ { MAD_F(0x048f5f9b) /* 0.285003285 */, 18 }, + /* 4520 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 18 }, + /* 4521 */ { MAD_F(0x04900ff8) /* 0.285171479 */, 18 }, + /* 4522 */ { MAD_F(0x04906829) /* 0.285255584 */, 18 }, + /* 4523 */ { MAD_F(0x0490c05b) /* 0.285339697 */, 18 }, + /* 4524 */ { MAD_F(0x04911890) /* 0.285423815 */, 18 }, + /* 4525 */ { MAD_F(0x049170c6) /* 0.285507939 */, 18 }, + /* 4526 */ { MAD_F(0x0491c8fd) /* 0.285592070 */, 18 }, + /* 4527 */ { MAD_F(0x04922137) /* 0.285676207 */, 18 }, + + /* 4528 */ { MAD_F(0x04927972) /* 0.285760350 */, 18 }, + /* 4529 */ { MAD_F(0x0492d1ae) /* 0.285844499 */, 18 }, + /* 4530 */ { MAD_F(0x049329ed) /* 0.285928655 */, 18 }, + /* 4531 */ { MAD_F(0x0493822c) /* 0.286012816 */, 18 }, + /* 4532 */ { MAD_F(0x0493da6e) /* 0.286096984 */, 18 }, + /* 4533 */ { MAD_F(0x049432b1) /* 0.286181158 */, 18 }, + /* 4534 */ { MAD_F(0x04948af6) /* 0.286265338 */, 18 }, + /* 4535 */ { MAD_F(0x0494e33d) /* 0.286349525 */, 18 }, + /* 4536 */ { MAD_F(0x04953b85) /* 0.286433717 */, 18 }, + /* 4537 */ { MAD_F(0x049593cf) /* 0.286517916 */, 18 }, + /* 4538 */ { MAD_F(0x0495ec1b) /* 0.286602121 */, 18 }, + /* 4539 */ { MAD_F(0x04964468) /* 0.286686332 */, 18 }, + /* 4540 */ { MAD_F(0x04969cb7) /* 0.286770550 */, 18 }, + /* 4541 */ { MAD_F(0x0496f508) /* 0.286854773 */, 18 }, + /* 4542 */ { MAD_F(0x04974d5a) /* 0.286939003 */, 18 }, + /* 4543 */ { MAD_F(0x0497a5ae) /* 0.287023239 */, 18 }, + + /* 4544 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 18 }, + /* 4545 */ { MAD_F(0x0498565a) /* 0.287191729 */, 18 }, + /* 4546 */ { MAD_F(0x0498aeb3) /* 0.287275983 */, 18 }, + /* 4547 */ { MAD_F(0x0499070e) /* 0.287360244 */, 18 }, + /* 4548 */ { MAD_F(0x04995f6a) /* 0.287444511 */, 18 }, + /* 4549 */ { MAD_F(0x0499b7c8) /* 0.287528784 */, 18 }, + /* 4550 */ { MAD_F(0x049a1027) /* 0.287613063 */, 18 }, + /* 4551 */ { MAD_F(0x049a6889) /* 0.287697348 */, 18 }, + /* 4552 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 18 }, + /* 4553 */ { MAD_F(0x049b1950) /* 0.287865937 */, 18 }, + /* 4554 */ { MAD_F(0x049b71b6) /* 0.287950241 */, 18 }, + /* 4555 */ { MAD_F(0x049bca1e) /* 0.288034551 */, 18 }, + /* 4556 */ { MAD_F(0x049c2287) /* 0.288118867 */, 18 }, + /* 4557 */ { MAD_F(0x049c7af2) /* 0.288203190 */, 18 }, + /* 4558 */ { MAD_F(0x049cd35f) /* 0.288287518 */, 18 }, + /* 4559 */ { MAD_F(0x049d2bce) /* 0.288371853 */, 18 }, + + /* 4560 */ { MAD_F(0x049d843e) /* 0.288456194 */, 18 }, + /* 4561 */ { MAD_F(0x049ddcaf) /* 0.288540541 */, 18 }, + /* 4562 */ { MAD_F(0x049e3523) /* 0.288624894 */, 18 }, + /* 4563 */ { MAD_F(0x049e8d98) /* 0.288709253 */, 18 }, + /* 4564 */ { MAD_F(0x049ee60e) /* 0.288793619 */, 18 }, + /* 4565 */ { MAD_F(0x049f3e87) /* 0.288877990 */, 18 }, + /* 4566 */ { MAD_F(0x049f9701) /* 0.288962368 */, 18 }, + /* 4567 */ { MAD_F(0x049fef7c) /* 0.289046752 */, 18 }, + /* 4568 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 18 }, + /* 4569 */ { MAD_F(0x04a0a079) /* 0.289215538 */, 18 }, + /* 4570 */ { MAD_F(0x04a0f8f9) /* 0.289299941 */, 18 }, + /* 4571 */ { MAD_F(0x04a1517c) /* 0.289384349 */, 18 }, + /* 4572 */ { MAD_F(0x04a1a9ff) /* 0.289468764 */, 18 }, + /* 4573 */ { MAD_F(0x04a20285) /* 0.289553185 */, 18 }, + /* 4574 */ { MAD_F(0x04a25b0c) /* 0.289637612 */, 18 }, + /* 4575 */ { MAD_F(0x04a2b395) /* 0.289722045 */, 18 }, + + /* 4576 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 18 }, + /* 4577 */ { MAD_F(0x04a364ac) /* 0.289890930 */, 18 }, + /* 4578 */ { MAD_F(0x04a3bd3a) /* 0.289975382 */, 18 }, + /* 4579 */ { MAD_F(0x04a415c9) /* 0.290059840 */, 18 }, + /* 4580 */ { MAD_F(0x04a46e5a) /* 0.290144304 */, 18 }, + /* 4581 */ { MAD_F(0x04a4c6ed) /* 0.290228774 */, 18 }, + /* 4582 */ { MAD_F(0x04a51f81) /* 0.290313250 */, 18 }, + /* 4583 */ { MAD_F(0x04a57818) /* 0.290397733 */, 18 }, + /* 4584 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 18 }, + /* 4585 */ { MAD_F(0x04a62949) /* 0.290566716 */, 18 }, + /* 4586 */ { MAD_F(0x04a681e4) /* 0.290651217 */, 18 }, + /* 4587 */ { MAD_F(0x04a6da80) /* 0.290735724 */, 18 }, + /* 4588 */ { MAD_F(0x04a7331f) /* 0.290820237 */, 18 }, + /* 4589 */ { MAD_F(0x04a78bbf) /* 0.290904756 */, 18 }, + /* 4590 */ { MAD_F(0x04a7e460) /* 0.290989281 */, 18 }, + /* 4591 */ { MAD_F(0x04a83d03) /* 0.291073813 */, 18 }, + + /* 4592 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 18 }, + /* 4593 */ { MAD_F(0x04a8ee4f) /* 0.291242894 */, 18 }, + /* 4594 */ { MAD_F(0x04a946f7) /* 0.291327444 */, 18 }, + /* 4595 */ { MAD_F(0x04a99fa1) /* 0.291412001 */, 18 }, + /* 4596 */ { MAD_F(0x04a9f84c) /* 0.291496563 */, 18 }, + /* 4597 */ { MAD_F(0x04aa50fa) /* 0.291581131 */, 18 }, + /* 4598 */ { MAD_F(0x04aaa9a8) /* 0.291665706 */, 18 }, + /* 4599 */ { MAD_F(0x04ab0259) /* 0.291750286 */, 18 }, + /* 4600 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 18 }, + /* 4601 */ { MAD_F(0x04abb3bf) /* 0.291919466 */, 18 }, + /* 4602 */ { MAD_F(0x04ac0c74) /* 0.292004065 */, 18 }, + /* 4603 */ { MAD_F(0x04ac652b) /* 0.292088670 */, 18 }, + /* 4604 */ { MAD_F(0x04acbde4) /* 0.292173281 */, 18 }, + /* 4605 */ { MAD_F(0x04ad169e) /* 0.292257899 */, 18 }, + /* 4606 */ { MAD_F(0x04ad6f5a) /* 0.292342522 */, 18 }, + /* 4607 */ { MAD_F(0x04adc818) /* 0.292427152 */, 18 }, + + /* 4608 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 18 }, + /* 4609 */ { MAD_F(0x04ae7998) /* 0.292596430 */, 18 }, + /* 4610 */ { MAD_F(0x04aed25a) /* 0.292681078 */, 18 }, + /* 4611 */ { MAD_F(0x04af2b1e) /* 0.292765732 */, 18 }, + /* 4612 */ { MAD_F(0x04af83e4) /* 0.292850392 */, 18 }, + /* 4613 */ { MAD_F(0x04afdcac) /* 0.292935058 */, 18 }, + /* 4614 */ { MAD_F(0x04b03575) /* 0.293019731 */, 18 }, + /* 4615 */ { MAD_F(0x04b08e40) /* 0.293104409 */, 18 }, + /* 4616 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 18 }, + /* 4617 */ { MAD_F(0x04b13fda) /* 0.293273785 */, 18 }, + /* 4618 */ { MAD_F(0x04b198aa) /* 0.293358482 */, 18 }, + /* 4619 */ { MAD_F(0x04b1f17b) /* 0.293443185 */, 18 }, + /* 4620 */ { MAD_F(0x04b24a4e) /* 0.293527894 */, 18 }, + /* 4621 */ { MAD_F(0x04b2a322) /* 0.293612609 */, 18 }, + /* 4622 */ { MAD_F(0x04b2fbf9) /* 0.293697331 */, 18 }, + /* 4623 */ { MAD_F(0x04b354d1) /* 0.293782058 */, 18 }, + + /* 4624 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 18 }, + /* 4625 */ { MAD_F(0x04b40685) /* 0.293951532 */, 18 }, + /* 4626 */ { MAD_F(0x04b45f62) /* 0.294036278 */, 18 }, + /* 4627 */ { MAD_F(0x04b4b840) /* 0.294121029 */, 18 }, + /* 4628 */ { MAD_F(0x04b51120) /* 0.294205788 */, 18 }, + /* 4629 */ { MAD_F(0x04b56a02) /* 0.294290552 */, 18 }, + /* 4630 */ { MAD_F(0x04b5c2e6) /* 0.294375322 */, 18 }, + /* 4631 */ { MAD_F(0x04b61bcb) /* 0.294460098 */, 18 }, + /* 4632 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 18 }, + /* 4633 */ { MAD_F(0x04b6cd99) /* 0.294629669 */, 18 }, + /* 4634 */ { MAD_F(0x04b72683) /* 0.294714464 */, 18 }, + /* 4635 */ { MAD_F(0x04b77f6f) /* 0.294799265 */, 18 }, + /* 4636 */ { MAD_F(0x04b7d85c) /* 0.294884072 */, 18 }, + /* 4637 */ { MAD_F(0x04b8314b) /* 0.294968885 */, 18 }, + /* 4638 */ { MAD_F(0x04b88a3b) /* 0.295053704 */, 18 }, + /* 4639 */ { MAD_F(0x04b8e32d) /* 0.295138529 */, 18 }, + + /* 4640 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 18 }, + /* 4641 */ { MAD_F(0x04b99516) /* 0.295308197 */, 18 }, + /* 4642 */ { MAD_F(0x04b9ee0d) /* 0.295393041 */, 18 }, + /* 4643 */ { MAD_F(0x04ba4706) /* 0.295477890 */, 18 }, + /* 4644 */ { MAD_F(0x04baa000) /* 0.295562746 */, 18 }, + /* 4645 */ { MAD_F(0x04baf8fc) /* 0.295647608 */, 18 }, + /* 4646 */ { MAD_F(0x04bb51fa) /* 0.295732476 */, 18 }, + /* 4647 */ { MAD_F(0x04bbaaf9) /* 0.295817349 */, 18 }, + /* 4648 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 18 }, + /* 4649 */ { MAD_F(0x04bc5cfc) /* 0.295987115 */, 18 }, + /* 4650 */ { MAD_F(0x04bcb600) /* 0.296072008 */, 18 }, + /* 4651 */ { MAD_F(0x04bd0f06) /* 0.296156906 */, 18 }, + /* 4652 */ { MAD_F(0x04bd680d) /* 0.296241810 */, 18 }, + /* 4653 */ { MAD_F(0x04bdc116) /* 0.296326721 */, 18 }, + /* 4654 */ { MAD_F(0x04be1a21) /* 0.296411637 */, 18 }, + /* 4655 */ { MAD_F(0x04be732d) /* 0.296496560 */, 18 }, + + /* 4656 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 18 }, + /* 4657 */ { MAD_F(0x04bf254a) /* 0.296666423 */, 18 }, + /* 4658 */ { MAD_F(0x04bf7e5b) /* 0.296751364 */, 18 }, + /* 4659 */ { MAD_F(0x04bfd76e) /* 0.296836311 */, 18 }, + /* 4660 */ { MAD_F(0x04c03083) /* 0.296921264 */, 18 }, + /* 4661 */ { MAD_F(0x04c08999) /* 0.297006223 */, 18 }, + /* 4662 */ { MAD_F(0x04c0e2b0) /* 0.297091188 */, 18 }, + /* 4663 */ { MAD_F(0x04c13bca) /* 0.297176159 */, 18 }, + /* 4664 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 18 }, + /* 4665 */ { MAD_F(0x04c1ee01) /* 0.297346120 */, 18 }, + /* 4666 */ { MAD_F(0x04c2471f) /* 0.297431109 */, 18 }, + /* 4667 */ { MAD_F(0x04c2a03f) /* 0.297516105 */, 18 }, + /* 4668 */ { MAD_F(0x04c2f960) /* 0.297601106 */, 18 }, + /* 4669 */ { MAD_F(0x04c35283) /* 0.297686114 */, 18 }, + /* 4670 */ { MAD_F(0x04c3aba8) /* 0.297771128 */, 18 }, + /* 4671 */ { MAD_F(0x04c404ce) /* 0.297856147 */, 18 }, + + /* 4672 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 18 }, + /* 4673 */ { MAD_F(0x04c4b720) /* 0.298026205 */, 18 }, + /* 4674 */ { MAD_F(0x04c5104b) /* 0.298111243 */, 18 }, + /* 4675 */ { MAD_F(0x04c56978) /* 0.298196287 */, 18 }, + /* 4676 */ { MAD_F(0x04c5c2a7) /* 0.298281337 */, 18 }, + /* 4677 */ { MAD_F(0x04c61bd7) /* 0.298366393 */, 18 }, + /* 4678 */ { MAD_F(0x04c67508) /* 0.298451456 */, 18 }, + /* 4679 */ { MAD_F(0x04c6ce3c) /* 0.298536524 */, 18 }, + /* 4680 */ { MAD_F(0x04c72771) /* 0.298621598 */, 18 }, + /* 4681 */ { MAD_F(0x04c780a7) /* 0.298706679 */, 18 }, + /* 4682 */ { MAD_F(0x04c7d9df) /* 0.298791765 */, 18 }, + /* 4683 */ { MAD_F(0x04c83319) /* 0.298876858 */, 18 }, + /* 4684 */ { MAD_F(0x04c88c55) /* 0.298961956 */, 18 }, + /* 4685 */ { MAD_F(0x04c8e592) /* 0.299047061 */, 18 }, + /* 4686 */ { MAD_F(0x04c93ed1) /* 0.299132172 */, 18 }, + /* 4687 */ { MAD_F(0x04c99811) /* 0.299217288 */, 18 }, + + /* 4688 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 18 }, + /* 4689 */ { MAD_F(0x04ca4a97) /* 0.299387540 */, 18 }, + /* 4690 */ { MAD_F(0x04caa3dc) /* 0.299472675 */, 18 }, + /* 4691 */ { MAD_F(0x04cafd23) /* 0.299557816 */, 18 }, + /* 4692 */ { MAD_F(0x04cb566b) /* 0.299642963 */, 18 }, + /* 4693 */ { MAD_F(0x04cbafb5) /* 0.299728116 */, 18 }, + /* 4694 */ { MAD_F(0x04cc0901) /* 0.299813275 */, 18 }, + /* 4695 */ { MAD_F(0x04cc624e) /* 0.299898440 */, 18 }, + /* 4696 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 18 }, + /* 4697 */ { MAD_F(0x04cd14ee) /* 0.300068789 */, 18 }, + /* 4698 */ { MAD_F(0x04cd6e40) /* 0.300153972 */, 18 }, + /* 4699 */ { MAD_F(0x04cdc794) /* 0.300239161 */, 18 }, + /* 4700 */ { MAD_F(0x04ce20e9) /* 0.300324357 */, 18 }, + /* 4701 */ { MAD_F(0x04ce7a40) /* 0.300409558 */, 18 }, + /* 4702 */ { MAD_F(0x04ced399) /* 0.300494765 */, 18 }, + /* 4703 */ { MAD_F(0x04cf2cf3) /* 0.300579979 */, 18 }, + + /* 4704 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 18 }, + /* 4705 */ { MAD_F(0x04cfdfad) /* 0.300750424 */, 18 }, + /* 4706 */ { MAD_F(0x04d0390c) /* 0.300835656 */, 18 }, + /* 4707 */ { MAD_F(0x04d0926d) /* 0.300920893 */, 18 }, + /* 4708 */ { MAD_F(0x04d0ebcf) /* 0.301006137 */, 18 }, + /* 4709 */ { MAD_F(0x04d14533) /* 0.301091387 */, 18 }, + /* 4710 */ { MAD_F(0x04d19e99) /* 0.301176643 */, 18 }, + /* 4711 */ { MAD_F(0x04d1f800) /* 0.301261904 */, 18 }, + /* 4712 */ { MAD_F(0x04d25169) /* 0.301347172 */, 18 }, + /* 4713 */ { MAD_F(0x04d2aad4) /* 0.301432446 */, 18 }, + /* 4714 */ { MAD_F(0x04d30440) /* 0.301517726 */, 18 }, + /* 4715 */ { MAD_F(0x04d35dae) /* 0.301603012 */, 18 }, + /* 4716 */ { MAD_F(0x04d3b71d) /* 0.301688304 */, 18 }, + /* 4717 */ { MAD_F(0x04d4108e) /* 0.301773602 */, 18 }, + /* 4718 */ { MAD_F(0x04d46a01) /* 0.301858906 */, 18 }, + /* 4719 */ { MAD_F(0x04d4c375) /* 0.301944216 */, 18 }, + + /* 4720 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 18 }, + /* 4721 */ { MAD_F(0x04d57662) /* 0.302114854 */, 18 }, + /* 4722 */ { MAD_F(0x04d5cfdb) /* 0.302200182 */, 18 }, + /* 4723 */ { MAD_F(0x04d62956) /* 0.302285516 */, 18 }, + /* 4724 */ { MAD_F(0x04d682d2) /* 0.302370856 */, 18 }, + /* 4725 */ { MAD_F(0x04d6dc50) /* 0.302456203 */, 18 }, + /* 4726 */ { MAD_F(0x04d735d0) /* 0.302541555 */, 18 }, + /* 4727 */ { MAD_F(0x04d78f51) /* 0.302626913 */, 18 }, + /* 4728 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 18 }, + /* 4729 */ { MAD_F(0x04d84258) /* 0.302797648 */, 18 }, + /* 4730 */ { MAD_F(0x04d89bde) /* 0.302883024 */, 18 }, + /* 4731 */ { MAD_F(0x04d8f566) /* 0.302968406 */, 18 }, + /* 4732 */ { MAD_F(0x04d94eef) /* 0.303053794 */, 18 }, + /* 4733 */ { MAD_F(0x04d9a87a) /* 0.303139189 */, 18 }, + /* 4734 */ { MAD_F(0x04da0207) /* 0.303224589 */, 18 }, + /* 4735 */ { MAD_F(0x04da5b95) /* 0.303309995 */, 18 }, + + /* 4736 */ { MAD_F(0x04dab524) /* 0.303395408 */, 18 }, + /* 4737 */ { MAD_F(0x04db0eb6) /* 0.303480826 */, 18 }, + /* 4738 */ { MAD_F(0x04db6849) /* 0.303566251 */, 18 }, + /* 4739 */ { MAD_F(0x04dbc1dd) /* 0.303651681 */, 18 }, + /* 4740 */ { MAD_F(0x04dc1b73) /* 0.303737117 */, 18 }, + /* 4741 */ { MAD_F(0x04dc750b) /* 0.303822560 */, 18 }, + /* 4742 */ { MAD_F(0x04dccea5) /* 0.303908008 */, 18 }, + /* 4743 */ { MAD_F(0x04dd2840) /* 0.303993463 */, 18 }, + /* 4744 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 18 }, + /* 4745 */ { MAD_F(0x04dddb7a) /* 0.304164390 */, 18 }, + /* 4746 */ { MAD_F(0x04de351a) /* 0.304249862 */, 18 }, + /* 4747 */ { MAD_F(0x04de8ebc) /* 0.304335340 */, 18 }, + /* 4748 */ { MAD_F(0x04dee85f) /* 0.304420825 */, 18 }, + /* 4749 */ { MAD_F(0x04df4203) /* 0.304506315 */, 18 }, + /* 4750 */ { MAD_F(0x04df9baa) /* 0.304591812 */, 18 }, + /* 4751 */ { MAD_F(0x04dff552) /* 0.304677314 */, 18 }, + + /* 4752 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 18 }, + /* 4753 */ { MAD_F(0x04e0a8a6) /* 0.304848337 */, 18 }, + /* 4754 */ { MAD_F(0x04e10253) /* 0.304933858 */, 18 }, + /* 4755 */ { MAD_F(0x04e15c01) /* 0.305019384 */, 18 }, + /* 4756 */ { MAD_F(0x04e1b5b1) /* 0.305104917 */, 18 }, + /* 4757 */ { MAD_F(0x04e20f63) /* 0.305190455 */, 18 }, + /* 4758 */ { MAD_F(0x04e26916) /* 0.305275999 */, 18 }, + /* 4759 */ { MAD_F(0x04e2c2cb) /* 0.305361550 */, 18 }, + /* 4760 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 18 }, + /* 4761 */ { MAD_F(0x04e37639) /* 0.305532669 */, 18 }, + /* 4762 */ { MAD_F(0x04e3cff3) /* 0.305618237 */, 18 }, + /* 4763 */ { MAD_F(0x04e429ae) /* 0.305703811 */, 18 }, + /* 4764 */ { MAD_F(0x04e4836b) /* 0.305789392 */, 18 }, + /* 4765 */ { MAD_F(0x04e4dd29) /* 0.305874978 */, 18 }, + /* 4766 */ { MAD_F(0x04e536e9) /* 0.305960571 */, 18 }, + /* 4767 */ { MAD_F(0x04e590ab) /* 0.306046169 */, 18 }, + + /* 4768 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 18 }, + /* 4769 */ { MAD_F(0x04e64433) /* 0.306217383 */, 18 }, + /* 4770 */ { MAD_F(0x04e69df9) /* 0.306303000 */, 18 }, + /* 4771 */ { MAD_F(0x04e6f7c1) /* 0.306388622 */, 18 }, + /* 4772 */ { MAD_F(0x04e7518b) /* 0.306474250 */, 18 }, + /* 4773 */ { MAD_F(0x04e7ab56) /* 0.306559885 */, 18 }, + /* 4774 */ { MAD_F(0x04e80523) /* 0.306645525 */, 18 }, + /* 4775 */ { MAD_F(0x04e85ef2) /* 0.306731171 */, 18 }, + /* 4776 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 18 }, + /* 4777 */ { MAD_F(0x04e91293) /* 0.306902481 */, 18 }, + /* 4778 */ { MAD_F(0x04e96c67) /* 0.306988145 */, 18 }, + /* 4779 */ { MAD_F(0x04e9c63b) /* 0.307073816 */, 18 }, + /* 4780 */ { MAD_F(0x04ea2012) /* 0.307159492 */, 18 }, + /* 4781 */ { MAD_F(0x04ea79ea) /* 0.307245174 */, 18 }, + /* 4782 */ { MAD_F(0x04ead3c4) /* 0.307330862 */, 18 }, + /* 4783 */ { MAD_F(0x04eb2d9f) /* 0.307416556 */, 18 }, + + /* 4784 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 18 }, + /* 4785 */ { MAD_F(0x04ebe15b) /* 0.307587962 */, 18 }, + /* 4786 */ { MAD_F(0x04ec3b3b) /* 0.307673674 */, 18 }, + /* 4787 */ { MAD_F(0x04ec951c) /* 0.307759392 */, 18 }, + /* 4788 */ { MAD_F(0x04ecef00) /* 0.307845115 */, 18 }, + /* 4789 */ { MAD_F(0x04ed48e5) /* 0.307930845 */, 18 }, + /* 4790 */ { MAD_F(0x04eda2cb) /* 0.308016581 */, 18 }, + /* 4791 */ { MAD_F(0x04edfcb3) /* 0.308102323 */, 18 }, + /* 4792 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 18 }, + /* 4793 */ { MAD_F(0x04eeb088) /* 0.308273824 */, 18 }, + /* 4794 */ { MAD_F(0x04ef0a75) /* 0.308359584 */, 18 }, + /* 4795 */ { MAD_F(0x04ef6464) /* 0.308445350 */, 18 }, + /* 4796 */ { MAD_F(0x04efbe54) /* 0.308531121 */, 18 }, + /* 4797 */ { MAD_F(0x04f01846) /* 0.308616899 */, 18 }, + /* 4798 */ { MAD_F(0x04f07239) /* 0.308702682 */, 18 }, + /* 4799 */ { MAD_F(0x04f0cc2e) /* 0.308788472 */, 18 }, + + /* 4800 */ { MAD_F(0x04f12624) /* 0.308874267 */, 18 }, + /* 4801 */ { MAD_F(0x04f1801d) /* 0.308960068 */, 18 }, + /* 4802 */ { MAD_F(0x04f1da16) /* 0.309045876 */, 18 }, + /* 4803 */ { MAD_F(0x04f23412) /* 0.309131689 */, 18 }, + /* 4804 */ { MAD_F(0x04f28e0f) /* 0.309217508 */, 18 }, + /* 4805 */ { MAD_F(0x04f2e80d) /* 0.309303334 */, 18 }, + /* 4806 */ { MAD_F(0x04f3420d) /* 0.309389165 */, 18 }, + /* 4807 */ { MAD_F(0x04f39c0f) /* 0.309475002 */, 18 }, + /* 4808 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 18 }, + /* 4809 */ { MAD_F(0x04f45017) /* 0.309646694 */, 18 }, + /* 4810 */ { MAD_F(0x04f4aa1e) /* 0.309732549 */, 18 }, + /* 4811 */ { MAD_F(0x04f50426) /* 0.309818410 */, 18 }, + /* 4812 */ { MAD_F(0x04f55e30) /* 0.309904277 */, 18 }, + /* 4813 */ { MAD_F(0x04f5b83b) /* 0.309990150 */, 18 }, + /* 4814 */ { MAD_F(0x04f61248) /* 0.310076028 */, 18 }, + /* 4815 */ { MAD_F(0x04f66c56) /* 0.310161913 */, 18 }, + + /* 4816 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 18 }, + /* 4817 */ { MAD_F(0x04f72078) /* 0.310333700 */, 18 }, + /* 4818 */ { MAD_F(0x04f77a8b) /* 0.310419603 */, 18 }, + /* 4819 */ { MAD_F(0x04f7d4a0) /* 0.310505511 */, 18 }, + /* 4820 */ { MAD_F(0x04f82eb7) /* 0.310591426 */, 18 }, + /* 4821 */ { MAD_F(0x04f888cf) /* 0.310677346 */, 18 }, + /* 4822 */ { MAD_F(0x04f8e2e9) /* 0.310763272 */, 18 }, + /* 4823 */ { MAD_F(0x04f93d04) /* 0.310849205 */, 18 }, + /* 4824 */ { MAD_F(0x04f99721) /* 0.310935143 */, 18 }, + /* 4825 */ { MAD_F(0x04f9f13f) /* 0.311021087 */, 18 }, + /* 4826 */ { MAD_F(0x04fa4b5f) /* 0.311107037 */, 18 }, + /* 4827 */ { MAD_F(0x04faa581) /* 0.311192993 */, 18 }, + /* 4828 */ { MAD_F(0x04faffa4) /* 0.311278955 */, 18 }, + /* 4829 */ { MAD_F(0x04fb59c9) /* 0.311364923 */, 18 }, + /* 4830 */ { MAD_F(0x04fbb3ef) /* 0.311450897 */, 18 }, + /* 4831 */ { MAD_F(0x04fc0e17) /* 0.311536877 */, 18 }, + + /* 4832 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 18 }, + /* 4833 */ { MAD_F(0x04fcc26c) /* 0.311708854 */, 18 }, + /* 4834 */ { MAD_F(0x04fd1c99) /* 0.311794851 */, 18 }, + /* 4835 */ { MAD_F(0x04fd76c7) /* 0.311880855 */, 18 }, + /* 4836 */ { MAD_F(0x04fdd0f7) /* 0.311966864 */, 18 }, + /* 4837 */ { MAD_F(0x04fe2b29) /* 0.312052880 */, 18 }, + /* 4838 */ { MAD_F(0x04fe855c) /* 0.312138901 */, 18 }, + /* 4839 */ { MAD_F(0x04fedf91) /* 0.312224928 */, 18 }, + /* 4840 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 18 }, + /* 4841 */ { MAD_F(0x04ff93ff) /* 0.312397000 */, 18 }, + /* 4842 */ { MAD_F(0x04ffee38) /* 0.312483045 */, 18 }, + /* 4843 */ { MAD_F(0x05004874) /* 0.312569096 */, 18 }, + /* 4844 */ { MAD_F(0x0500a2b0) /* 0.312655153 */, 18 }, + /* 4845 */ { MAD_F(0x0500fcef) /* 0.312741216 */, 18 }, + /* 4846 */ { MAD_F(0x0501572e) /* 0.312827284 */, 18 }, + /* 4847 */ { MAD_F(0x0501b170) /* 0.312913359 */, 18 }, + + /* 4848 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 18 }, + /* 4849 */ { MAD_F(0x050265f8) /* 0.313085526 */, 18 }, + /* 4850 */ { MAD_F(0x0502c03e) /* 0.313171618 */, 18 }, + /* 4851 */ { MAD_F(0x05031a86) /* 0.313257716 */, 18 }, + /* 4852 */ { MAD_F(0x050374cf) /* 0.313343820 */, 18 }, + /* 4853 */ { MAD_F(0x0503cf1a) /* 0.313429931 */, 18 }, + /* 4854 */ { MAD_F(0x05042967) /* 0.313516047 */, 18 }, + /* 4855 */ { MAD_F(0x050483b5) /* 0.313602168 */, 18 }, + /* 4856 */ { MAD_F(0x0504de05) /* 0.313688296 */, 18 }, + /* 4857 */ { MAD_F(0x05053856) /* 0.313774430 */, 18 }, + /* 4858 */ { MAD_F(0x050592a9) /* 0.313860570 */, 18 }, + /* 4859 */ { MAD_F(0x0505ecfd) /* 0.313946715 */, 18 }, + /* 4860 */ { MAD_F(0x05064754) /* 0.314032867 */, 18 }, + /* 4861 */ { MAD_F(0x0506a1ab) /* 0.314119024 */, 18 }, + /* 4862 */ { MAD_F(0x0506fc04) /* 0.314205187 */, 18 }, + /* 4863 */ { MAD_F(0x0507565f) /* 0.314291357 */, 18 }, + + /* 4864 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 18 }, + /* 4865 */ { MAD_F(0x05080b1a) /* 0.314463713 */, 18 }, + /* 4866 */ { MAD_F(0x05086579) /* 0.314549900 */, 18 }, + /* 4867 */ { MAD_F(0x0508bfdb) /* 0.314636092 */, 18 }, + /* 4868 */ { MAD_F(0x05091a3d) /* 0.314722291 */, 18 }, + /* 4869 */ { MAD_F(0x050974a2) /* 0.314808496 */, 18 }, + /* 4870 */ { MAD_F(0x0509cf08) /* 0.314894706 */, 18 }, + /* 4871 */ { MAD_F(0x050a296f) /* 0.314980923 */, 18 }, + /* 4872 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 18 }, + /* 4873 */ { MAD_F(0x050ade43) /* 0.315153373 */, 18 }, + /* 4874 */ { MAD_F(0x050b38af) /* 0.315239607 */, 18 }, + /* 4875 */ { MAD_F(0x050b931d) /* 0.315325847 */, 18 }, + /* 4876 */ { MAD_F(0x050bed8d) /* 0.315412093 */, 18 }, + /* 4877 */ { MAD_F(0x050c47fe) /* 0.315498345 */, 18 }, + /* 4878 */ { MAD_F(0x050ca271) /* 0.315584603 */, 18 }, + /* 4879 */ { MAD_F(0x050cfce5) /* 0.315670866 */, 18 }, + + /* 4880 */ { MAD_F(0x050d575b) /* 0.315757136 */, 18 }, + /* 4881 */ { MAD_F(0x050db1d2) /* 0.315843411 */, 18 }, + /* 4882 */ { MAD_F(0x050e0c4b) /* 0.315929693 */, 18 }, + /* 4883 */ { MAD_F(0x050e66c5) /* 0.316015980 */, 18 }, + /* 4884 */ { MAD_F(0x050ec141) /* 0.316102273 */, 18 }, + /* 4885 */ { MAD_F(0x050f1bbf) /* 0.316188572 */, 18 }, + /* 4886 */ { MAD_F(0x050f763e) /* 0.316274877 */, 18 }, + /* 4887 */ { MAD_F(0x050fd0bf) /* 0.316361187 */, 18 }, + /* 4888 */ { MAD_F(0x05102b42) /* 0.316447504 */, 18 }, + /* 4889 */ { MAD_F(0x051085c6) /* 0.316533826 */, 18 }, + /* 4890 */ { MAD_F(0x0510e04b) /* 0.316620155 */, 18 }, + /* 4891 */ { MAD_F(0x05113ad3) /* 0.316706489 */, 18 }, + /* 4892 */ { MAD_F(0x0511955b) /* 0.316792829 */, 18 }, + /* 4893 */ { MAD_F(0x0511efe6) /* 0.316879175 */, 18 }, + /* 4894 */ { MAD_F(0x05124a72) /* 0.316965527 */, 18 }, + /* 4895 */ { MAD_F(0x0512a4ff) /* 0.317051885 */, 18 }, + + /* 4896 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 18 }, + /* 4897 */ { MAD_F(0x05135a1f) /* 0.317224618 */, 18 }, + /* 4898 */ { MAD_F(0x0513b4b1) /* 0.317310994 */, 18 }, + /* 4899 */ { MAD_F(0x05140f45) /* 0.317397375 */, 18 }, + /* 4900 */ { MAD_F(0x051469da) /* 0.317483762 */, 18 }, + /* 4901 */ { MAD_F(0x0514c471) /* 0.317570155 */, 18 }, + /* 4902 */ { MAD_F(0x05151f0a) /* 0.317656554 */, 18 }, + /* 4903 */ { MAD_F(0x051579a4) /* 0.317742959 */, 18 }, + /* 4904 */ { MAD_F(0x0515d440) /* 0.317829370 */, 18 }, + /* 4905 */ { MAD_F(0x05162edd) /* 0.317915786 */, 18 }, + /* 4906 */ { MAD_F(0x0516897c) /* 0.318002209 */, 18 }, + /* 4907 */ { MAD_F(0x0516e41c) /* 0.318088637 */, 18 }, + /* 4908 */ { MAD_F(0x05173ebe) /* 0.318175071 */, 18 }, + /* 4909 */ { MAD_F(0x05179962) /* 0.318261511 */, 18 }, + /* 4910 */ { MAD_F(0x0517f407) /* 0.318347957 */, 18 }, + /* 4911 */ { MAD_F(0x05184eae) /* 0.318434409 */, 18 }, + + /* 4912 */ { MAD_F(0x0518a956) /* 0.318520867 */, 18 }, + /* 4913 */ { MAD_F(0x05190400) /* 0.318607330 */, 18 }, + /* 4914 */ { MAD_F(0x05195eab) /* 0.318693800 */, 18 }, + /* 4915 */ { MAD_F(0x0519b958) /* 0.318780275 */, 18 }, + /* 4916 */ { MAD_F(0x051a1407) /* 0.318866756 */, 18 }, + /* 4917 */ { MAD_F(0x051a6eb7) /* 0.318953243 */, 18 }, + /* 4918 */ { MAD_F(0x051ac969) /* 0.319039736 */, 18 }, + /* 4919 */ { MAD_F(0x051b241c) /* 0.319126235 */, 18 }, + /* 4920 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 18 }, + /* 4921 */ { MAD_F(0x051bd987) /* 0.319299250 */, 18 }, + /* 4922 */ { MAD_F(0x051c3440) /* 0.319385766 */, 18 }, + /* 4923 */ { MAD_F(0x051c8ef9) /* 0.319472288 */, 18 }, + /* 4924 */ { MAD_F(0x051ce9b4) /* 0.319558816 */, 18 }, + /* 4925 */ { MAD_F(0x051d4471) /* 0.319645350 */, 18 }, + /* 4926 */ { MAD_F(0x051d9f2f) /* 0.319731890 */, 18 }, + /* 4927 */ { MAD_F(0x051df9ef) /* 0.319818435 */, 18 }, + + /* 4928 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 18 }, + /* 4929 */ { MAD_F(0x051eaf74) /* 0.319991544 */, 18 }, + /* 4930 */ { MAD_F(0x051f0a38) /* 0.320078107 */, 18 }, + /* 4931 */ { MAD_F(0x051f64ff) /* 0.320164676 */, 18 }, + /* 4932 */ { MAD_F(0x051fbfc6) /* 0.320251251 */, 18 }, + /* 4933 */ { MAD_F(0x05201a90) /* 0.320337832 */, 18 }, + /* 4934 */ { MAD_F(0x0520755b) /* 0.320424419 */, 18 }, + /* 4935 */ { MAD_F(0x0520d027) /* 0.320511011 */, 18 }, + /* 4936 */ { MAD_F(0x05212af5) /* 0.320597609 */, 18 }, + /* 4937 */ { MAD_F(0x052185c5) /* 0.320684213 */, 18 }, + /* 4938 */ { MAD_F(0x0521e096) /* 0.320770823 */, 18 }, + /* 4939 */ { MAD_F(0x05223b69) /* 0.320857439 */, 18 }, + /* 4940 */ { MAD_F(0x0522963d) /* 0.320944061 */, 18 }, + /* 4941 */ { MAD_F(0x0522f113) /* 0.321030688 */, 18 }, + /* 4942 */ { MAD_F(0x05234bea) /* 0.321117322 */, 18 }, + /* 4943 */ { MAD_F(0x0523a6c3) /* 0.321203961 */, 18 }, + + /* 4944 */ { MAD_F(0x0524019e) /* 0.321290606 */, 18 }, + /* 4945 */ { MAD_F(0x05245c7a) /* 0.321377257 */, 18 }, + /* 4946 */ { MAD_F(0x0524b758) /* 0.321463913 */, 18 }, + /* 4947 */ { MAD_F(0x05251237) /* 0.321550576 */, 18 }, + /* 4948 */ { MAD_F(0x05256d18) /* 0.321637244 */, 18 }, + /* 4949 */ { MAD_F(0x0525c7fb) /* 0.321723919 */, 18 }, + /* 4950 */ { MAD_F(0x052622df) /* 0.321810599 */, 18 }, + /* 4951 */ { MAD_F(0x05267dc4) /* 0.321897285 */, 18 }, + /* 4952 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 18 }, + /* 4953 */ { MAD_F(0x05273394) /* 0.322070674 */, 18 }, + /* 4954 */ { MAD_F(0x05278e7e) /* 0.322157377 */, 18 }, + /* 4955 */ { MAD_F(0x0527e96a) /* 0.322244087 */, 18 }, + /* 4956 */ { MAD_F(0x05284457) /* 0.322330802 */, 18 }, + /* 4957 */ { MAD_F(0x05289f46) /* 0.322417523 */, 18 }, + /* 4958 */ { MAD_F(0x0528fa37) /* 0.322504249 */, 18 }, + /* 4959 */ { MAD_F(0x05295529) /* 0.322590982 */, 18 }, + + /* 4960 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 18 }, + /* 4961 */ { MAD_F(0x052a0b12) /* 0.322764465 */, 18 }, + /* 4962 */ { MAD_F(0x052a6609) /* 0.322851215 */, 18 }, + /* 4963 */ { MAD_F(0x052ac101) /* 0.322937971 */, 18 }, + /* 4964 */ { MAD_F(0x052b1bfb) /* 0.323024732 */, 18 }, + /* 4965 */ { MAD_F(0x052b76f7) /* 0.323111500 */, 18 }, + /* 4966 */ { MAD_F(0x052bd1f4) /* 0.323198273 */, 18 }, + /* 4967 */ { MAD_F(0x052c2cf2) /* 0.323285052 */, 18 }, + /* 4968 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 18 }, + /* 4969 */ { MAD_F(0x052ce2f4) /* 0.323458628 */, 18 }, + /* 4970 */ { MAD_F(0x052d3df7) /* 0.323545425 */, 18 }, + /* 4971 */ { MAD_F(0x052d98fc) /* 0.323632227 */, 18 }, + /* 4972 */ { MAD_F(0x052df403) /* 0.323719036 */, 18 }, + /* 4973 */ { MAD_F(0x052e4f0b) /* 0.323805850 */, 18 }, + /* 4974 */ { MAD_F(0x052eaa14) /* 0.323892670 */, 18 }, + /* 4975 */ { MAD_F(0x052f051f) /* 0.323979496 */, 18 }, + + /* 4976 */ { MAD_F(0x052f602c) /* 0.324066327 */, 18 }, + /* 4977 */ { MAD_F(0x052fbb3a) /* 0.324153165 */, 18 }, + /* 4978 */ { MAD_F(0x0530164a) /* 0.324240008 */, 18 }, + /* 4979 */ { MAD_F(0x0530715b) /* 0.324326857 */, 18 }, + /* 4980 */ { MAD_F(0x0530cc6e) /* 0.324413712 */, 18 }, + /* 4981 */ { MAD_F(0x05312783) /* 0.324500572 */, 18 }, + /* 4982 */ { MAD_F(0x05318299) /* 0.324587439 */, 18 }, + /* 4983 */ { MAD_F(0x0531ddb0) /* 0.324674311 */, 18 }, + /* 4984 */ { MAD_F(0x053238ca) /* 0.324761189 */, 18 }, + /* 4985 */ { MAD_F(0x053293e4) /* 0.324848073 */, 18 }, + /* 4986 */ { MAD_F(0x0532ef01) /* 0.324934963 */, 18 }, + /* 4987 */ { MAD_F(0x05334a1e) /* 0.325021858 */, 18 }, + /* 4988 */ { MAD_F(0x0533a53e) /* 0.325108760 */, 18 }, + /* 4989 */ { MAD_F(0x0534005f) /* 0.325195667 */, 18 }, + /* 4990 */ { MAD_F(0x05345b81) /* 0.325282580 */, 18 }, + /* 4991 */ { MAD_F(0x0534b6a5) /* 0.325369498 */, 18 }, + + /* 4992 */ { MAD_F(0x053511cb) /* 0.325456423 */, 18 }, + /* 4993 */ { MAD_F(0x05356cf2) /* 0.325543353 */, 18 }, + /* 4994 */ { MAD_F(0x0535c81b) /* 0.325630290 */, 18 }, + /* 4995 */ { MAD_F(0x05362345) /* 0.325717232 */, 18 }, + /* 4996 */ { MAD_F(0x05367e71) /* 0.325804179 */, 18 }, + /* 4997 */ { MAD_F(0x0536d99f) /* 0.325891133 */, 18 }, + /* 4998 */ { MAD_F(0x053734ce) /* 0.325978092 */, 18 }, + /* 4999 */ { MAD_F(0x05378ffe) /* 0.326065057 */, 18 }, + /* 5000 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 18 }, + /* 5001 */ { MAD_F(0x05384664) /* 0.326239005 */, 18 }, + /* 5002 */ { MAD_F(0x0538a199) /* 0.326325988 */, 18 }, + /* 5003 */ { MAD_F(0x0538fcd0) /* 0.326412976 */, 18 }, + /* 5004 */ { MAD_F(0x05395808) /* 0.326499970 */, 18 }, + /* 5005 */ { MAD_F(0x0539b342) /* 0.326586970 */, 18 }, + /* 5006 */ { MAD_F(0x053a0e7d) /* 0.326673976 */, 18 }, + /* 5007 */ { MAD_F(0x053a69ba) /* 0.326760988 */, 18 }, + + /* 5008 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 18 }, + /* 5009 */ { MAD_F(0x053b2039) /* 0.326935028 */, 18 }, + /* 5010 */ { MAD_F(0x053b7b7b) /* 0.327022057 */, 18 }, + /* 5011 */ { MAD_F(0x053bd6be) /* 0.327109092 */, 18 }, + /* 5012 */ { MAD_F(0x053c3203) /* 0.327196132 */, 18 }, + /* 5013 */ { MAD_F(0x053c8d49) /* 0.327283178 */, 18 }, + /* 5014 */ { MAD_F(0x053ce891) /* 0.327370231 */, 18 }, + /* 5015 */ { MAD_F(0x053d43da) /* 0.327457288 */, 18 }, + /* 5016 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 18 }, + /* 5017 */ { MAD_F(0x053dfa72) /* 0.327631421 */, 18 }, + /* 5018 */ { MAD_F(0x053e55c0) /* 0.327718497 */, 18 }, + /* 5019 */ { MAD_F(0x053eb10f) /* 0.327805578 */, 18 }, + /* 5020 */ { MAD_F(0x053f0c61) /* 0.327892665 */, 18 }, + /* 5021 */ { MAD_F(0x053f67b3) /* 0.327979757 */, 18 }, + /* 5022 */ { MAD_F(0x053fc308) /* 0.328066855 */, 18 }, + /* 5023 */ { MAD_F(0x05401e5e) /* 0.328153960 */, 18 }, + + /* 5024 */ { MAD_F(0x054079b5) /* 0.328241070 */, 18 }, + /* 5025 */ { MAD_F(0x0540d50e) /* 0.328328185 */, 18 }, + /* 5026 */ { MAD_F(0x05413068) /* 0.328415307 */, 18 }, + /* 5027 */ { MAD_F(0x05418bc4) /* 0.328502434 */, 18 }, + /* 5028 */ { MAD_F(0x0541e722) /* 0.328589567 */, 18 }, + /* 5029 */ { MAD_F(0x05424281) /* 0.328676706 */, 18 }, + /* 5030 */ { MAD_F(0x05429de2) /* 0.328763850 */, 18 }, + /* 5031 */ { MAD_F(0x0542f944) /* 0.328851001 */, 18 }, + /* 5032 */ { MAD_F(0x054354a8) /* 0.328938157 */, 18 }, + /* 5033 */ { MAD_F(0x0543b00d) /* 0.329025319 */, 18 }, + /* 5034 */ { MAD_F(0x05440b74) /* 0.329112486 */, 18 }, + /* 5035 */ { MAD_F(0x054466dd) /* 0.329199660 */, 18 }, + /* 5036 */ { MAD_F(0x0544c247) /* 0.329286839 */, 18 }, + /* 5037 */ { MAD_F(0x05451db2) /* 0.329374024 */, 18 }, + /* 5038 */ { MAD_F(0x0545791f) /* 0.329461215 */, 18 }, + /* 5039 */ { MAD_F(0x0545d48e) /* 0.329548411 */, 18 }, + + /* 5040 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 18 }, + /* 5041 */ { MAD_F(0x05468b70) /* 0.329722822 */, 18 }, + /* 5042 */ { MAD_F(0x0546e6e3) /* 0.329810036 */, 18 }, + /* 5043 */ { MAD_F(0x05474258) /* 0.329897255 */, 18 }, + /* 5044 */ { MAD_F(0x05479dce) /* 0.329984481 */, 18 }, + /* 5045 */ { MAD_F(0x0547f946) /* 0.330071712 */, 18 }, + /* 5046 */ { MAD_F(0x054854c0) /* 0.330158949 */, 18 }, + /* 5047 */ { MAD_F(0x0548b03b) /* 0.330246191 */, 18 }, + /* 5048 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 18 }, + /* 5049 */ { MAD_F(0x05496735) /* 0.330420694 */, 18 }, + /* 5050 */ { MAD_F(0x0549c2b5) /* 0.330507954 */, 18 }, + /* 5051 */ { MAD_F(0x054a1e36) /* 0.330595220 */, 18 }, + /* 5052 */ { MAD_F(0x054a79b9) /* 0.330682491 */, 18 }, + /* 5053 */ { MAD_F(0x054ad53d) /* 0.330769768 */, 18 }, + /* 5054 */ { MAD_F(0x054b30c3) /* 0.330857051 */, 18 }, + /* 5055 */ { MAD_F(0x054b8c4b) /* 0.330944340 */, 18 }, + + /* 5056 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 18 }, + /* 5057 */ { MAD_F(0x054c435e) /* 0.331118935 */, 18 }, + /* 5058 */ { MAD_F(0x054c9eea) /* 0.331206241 */, 18 }, + /* 5059 */ { MAD_F(0x054cfa78) /* 0.331293553 */, 18 }, + /* 5060 */ { MAD_F(0x054d5607) /* 0.331380870 */, 18 }, + /* 5061 */ { MAD_F(0x054db197) /* 0.331468193 */, 18 }, + /* 5062 */ { MAD_F(0x054e0d2a) /* 0.331555522 */, 18 }, + /* 5063 */ { MAD_F(0x054e68bd) /* 0.331642857 */, 18 }, + /* 5064 */ { MAD_F(0x054ec453) /* 0.331730198 */, 18 }, + /* 5065 */ { MAD_F(0x054f1fe9) /* 0.331817544 */, 18 }, + /* 5066 */ { MAD_F(0x054f7b82) /* 0.331904896 */, 18 }, + /* 5067 */ { MAD_F(0x054fd71c) /* 0.331992254 */, 18 }, + /* 5068 */ { MAD_F(0x055032b7) /* 0.332079617 */, 18 }, + /* 5069 */ { MAD_F(0x05508e54) /* 0.332166986 */, 18 }, + /* 5070 */ { MAD_F(0x0550e9f3) /* 0.332254361 */, 18 }, + /* 5071 */ { MAD_F(0x05514593) /* 0.332341742 */, 18 }, + + /* 5072 */ { MAD_F(0x0551a134) /* 0.332429129 */, 18 }, + /* 5073 */ { MAD_F(0x0551fcd8) /* 0.332516521 */, 18 }, + /* 5074 */ { MAD_F(0x0552587c) /* 0.332603919 */, 18 }, + /* 5075 */ { MAD_F(0x0552b423) /* 0.332691323 */, 18 }, + /* 5076 */ { MAD_F(0x05530fca) /* 0.332778732 */, 18 }, + /* 5077 */ { MAD_F(0x05536b74) /* 0.332866147 */, 18 }, + /* 5078 */ { MAD_F(0x0553c71f) /* 0.332953568 */, 18 }, + /* 5079 */ { MAD_F(0x055422cb) /* 0.333040995 */, 18 }, + /* 5080 */ { MAD_F(0x05547e79) /* 0.333128427 */, 18 }, + /* 5081 */ { MAD_F(0x0554da29) /* 0.333215865 */, 18 }, + /* 5082 */ { MAD_F(0x055535da) /* 0.333303309 */, 18 }, + /* 5083 */ { MAD_F(0x0555918c) /* 0.333390759 */, 18 }, + /* 5084 */ { MAD_F(0x0555ed40) /* 0.333478214 */, 18 }, + /* 5085 */ { MAD_F(0x055648f6) /* 0.333565675 */, 18 }, + /* 5086 */ { MAD_F(0x0556a4ad) /* 0.333653142 */, 18 }, + /* 5087 */ { MAD_F(0x05570066) /* 0.333740615 */, 18 }, + + /* 5088 */ { MAD_F(0x05575c20) /* 0.333828093 */, 18 }, + /* 5089 */ { MAD_F(0x0557b7dc) /* 0.333915577 */, 18 }, + /* 5090 */ { MAD_F(0x05581399) /* 0.334003067 */, 18 }, + /* 5091 */ { MAD_F(0x05586f58) /* 0.334090562 */, 18 }, + /* 5092 */ { MAD_F(0x0558cb19) /* 0.334178063 */, 18 }, + /* 5093 */ { MAD_F(0x055926db) /* 0.334265570 */, 18 }, + /* 5094 */ { MAD_F(0x0559829e) /* 0.334353083 */, 18 }, + /* 5095 */ { MAD_F(0x0559de63) /* 0.334440601 */, 18 }, + /* 5096 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 18 }, + /* 5097 */ { MAD_F(0x055a95f2) /* 0.334615655 */, 18 }, + /* 5098 */ { MAD_F(0x055af1bb) /* 0.334703191 */, 18 }, + /* 5099 */ { MAD_F(0x055b4d87) /* 0.334790732 */, 18 }, + /* 5100 */ { MAD_F(0x055ba953) /* 0.334878279 */, 18 }, + /* 5101 */ { MAD_F(0x055c0522) /* 0.334965832 */, 18 }, + /* 5102 */ { MAD_F(0x055c60f1) /* 0.335053391 */, 18 }, + /* 5103 */ { MAD_F(0x055cbcc3) /* 0.335140955 */, 18 }, + + /* 5104 */ { MAD_F(0x055d1896) /* 0.335228525 */, 18 }, + /* 5105 */ { MAD_F(0x055d746a) /* 0.335316100 */, 18 }, + /* 5106 */ { MAD_F(0x055dd040) /* 0.335403682 */, 18 }, + /* 5107 */ { MAD_F(0x055e2c17) /* 0.335491269 */, 18 }, + /* 5108 */ { MAD_F(0x055e87f0) /* 0.335578861 */, 18 }, + /* 5109 */ { MAD_F(0x055ee3cb) /* 0.335666460 */, 18 }, + /* 5110 */ { MAD_F(0x055f3fa7) /* 0.335754064 */, 18 }, + /* 5111 */ { MAD_F(0x055f9b85) /* 0.335841674 */, 18 }, + /* 5112 */ { MAD_F(0x055ff764) /* 0.335929290 */, 18 }, + /* 5113 */ { MAD_F(0x05605344) /* 0.336016911 */, 18 }, + /* 5114 */ { MAD_F(0x0560af27) /* 0.336104538 */, 18 }, + /* 5115 */ { MAD_F(0x05610b0a) /* 0.336192171 */, 18 }, + /* 5116 */ { MAD_F(0x056166f0) /* 0.336279809 */, 18 }, + /* 5117 */ { MAD_F(0x0561c2d7) /* 0.336367453 */, 18 }, + /* 5118 */ { MAD_F(0x05621ebf) /* 0.336455103 */, 18 }, + /* 5119 */ { MAD_F(0x05627aa9) /* 0.336542759 */, 18 }, + + /* 5120 */ { MAD_F(0x0562d694) /* 0.336630420 */, 18 }, + /* 5121 */ { MAD_F(0x05633281) /* 0.336718087 */, 18 }, + /* 5122 */ { MAD_F(0x05638e70) /* 0.336805760 */, 18 }, + /* 5123 */ { MAD_F(0x0563ea60) /* 0.336893439 */, 18 }, + /* 5124 */ { MAD_F(0x05644651) /* 0.336981123 */, 18 }, + /* 5125 */ { MAD_F(0x0564a244) /* 0.337068813 */, 18 }, + /* 5126 */ { MAD_F(0x0564fe39) /* 0.337156508 */, 18 }, + /* 5127 */ { MAD_F(0x05655a2f) /* 0.337244209 */, 18 }, + /* 5128 */ { MAD_F(0x0565b627) /* 0.337331916 */, 18 }, + /* 5129 */ { MAD_F(0x05661220) /* 0.337419629 */, 18 }, + /* 5130 */ { MAD_F(0x05666e1a) /* 0.337507347 */, 18 }, + /* 5131 */ { MAD_F(0x0566ca17) /* 0.337595071 */, 18 }, + /* 5132 */ { MAD_F(0x05672614) /* 0.337682801 */, 18 }, + /* 5133 */ { MAD_F(0x05678214) /* 0.337770537 */, 18 }, + /* 5134 */ { MAD_F(0x0567de15) /* 0.337858278 */, 18 }, + /* 5135 */ { MAD_F(0x05683a17) /* 0.337946025 */, 18 }, + + /* 5136 */ { MAD_F(0x0568961b) /* 0.338033777 */, 18 }, + /* 5137 */ { MAD_F(0x0568f220) /* 0.338121535 */, 18 }, + /* 5138 */ { MAD_F(0x05694e27) /* 0.338209299 */, 18 }, + /* 5139 */ { MAD_F(0x0569aa30) /* 0.338297069 */, 18 }, + /* 5140 */ { MAD_F(0x056a063a) /* 0.338384844 */, 18 }, + /* 5141 */ { MAD_F(0x056a6245) /* 0.338472625 */, 18 }, + /* 5142 */ { MAD_F(0x056abe52) /* 0.338560412 */, 18 }, + /* 5143 */ { MAD_F(0x056b1a61) /* 0.338648204 */, 18 }, + /* 5144 */ { MAD_F(0x056b7671) /* 0.338736002 */, 18 }, + /* 5145 */ { MAD_F(0x056bd283) /* 0.338823806 */, 18 }, + /* 5146 */ { MAD_F(0x056c2e96) /* 0.338911616 */, 18 }, + /* 5147 */ { MAD_F(0x056c8aab) /* 0.338999431 */, 18 }, + /* 5148 */ { MAD_F(0x056ce6c1) /* 0.339087252 */, 18 }, + /* 5149 */ { MAD_F(0x056d42d9) /* 0.339175078 */, 18 }, + /* 5150 */ { MAD_F(0x056d9ef2) /* 0.339262910 */, 18 }, + /* 5151 */ { MAD_F(0x056dfb0d) /* 0.339350748 */, 18 }, + + /* 5152 */ { MAD_F(0x056e5729) /* 0.339438592 */, 18 }, + /* 5153 */ { MAD_F(0x056eb347) /* 0.339526441 */, 18 }, + /* 5154 */ { MAD_F(0x056f0f66) /* 0.339614296 */, 18 }, + /* 5155 */ { MAD_F(0x056f6b87) /* 0.339702157 */, 18 }, + /* 5156 */ { MAD_F(0x056fc7aa) /* 0.339790023 */, 18 }, + /* 5157 */ { MAD_F(0x057023cd) /* 0.339877895 */, 18 }, + /* 5158 */ { MAD_F(0x05707ff3) /* 0.339965773 */, 18 }, + /* 5159 */ { MAD_F(0x0570dc1a) /* 0.340053656 */, 18 }, + /* 5160 */ { MAD_F(0x05713843) /* 0.340141545 */, 18 }, + /* 5161 */ { MAD_F(0x0571946d) /* 0.340229440 */, 18 }, + /* 5162 */ { MAD_F(0x0571f098) /* 0.340317340 */, 18 }, + /* 5163 */ { MAD_F(0x05724cc5) /* 0.340405246 */, 18 }, + /* 5164 */ { MAD_F(0x0572a8f4) /* 0.340493158 */, 18 }, + /* 5165 */ { MAD_F(0x05730524) /* 0.340581075 */, 18 }, + /* 5166 */ { MAD_F(0x05736156) /* 0.340668999 */, 18 }, + /* 5167 */ { MAD_F(0x0573bd89) /* 0.340756927 */, 18 }, + + /* 5168 */ { MAD_F(0x057419be) /* 0.340844862 */, 18 }, + /* 5169 */ { MAD_F(0x057475f4) /* 0.340932802 */, 18 }, + /* 5170 */ { MAD_F(0x0574d22c) /* 0.341020748 */, 18 }, + /* 5171 */ { MAD_F(0x05752e65) /* 0.341108699 */, 18 }, + /* 5172 */ { MAD_F(0x05758aa0) /* 0.341196656 */, 18 }, + /* 5173 */ { MAD_F(0x0575e6dc) /* 0.341284619 */, 18 }, + /* 5174 */ { MAD_F(0x0576431a) /* 0.341372587 */, 18 }, + /* 5175 */ { MAD_F(0x05769f59) /* 0.341460562 */, 18 }, + /* 5176 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 18 }, + /* 5177 */ { MAD_F(0x057757dd) /* 0.341636527 */, 18 }, + /* 5178 */ { MAD_F(0x0577b421) /* 0.341724518 */, 18 }, + /* 5179 */ { MAD_F(0x05781066) /* 0.341812515 */, 18 }, + /* 5180 */ { MAD_F(0x05786cad) /* 0.341900517 */, 18 }, + /* 5181 */ { MAD_F(0x0578c8f5) /* 0.341988525 */, 18 }, + /* 5182 */ { MAD_F(0x0579253f) /* 0.342076539 */, 18 }, + /* 5183 */ { MAD_F(0x0579818b) /* 0.342164558 */, 18 }, + + /* 5184 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 18 }, + /* 5185 */ { MAD_F(0x057a3a27) /* 0.342340614 */, 18 }, + /* 5186 */ { MAD_F(0x057a9677) /* 0.342428651 */, 18 }, + /* 5187 */ { MAD_F(0x057af2c8) /* 0.342516693 */, 18 }, + /* 5188 */ { MAD_F(0x057b4f1c) /* 0.342604741 */, 18 }, + /* 5189 */ { MAD_F(0x057bab70) /* 0.342692794 */, 18 }, + /* 5190 */ { MAD_F(0x057c07c6) /* 0.342780853 */, 18 }, + /* 5191 */ { MAD_F(0x057c641e) /* 0.342868918 */, 18 }, + /* 5192 */ { MAD_F(0x057cc077) /* 0.342956988 */, 18 }, + /* 5193 */ { MAD_F(0x057d1cd2) /* 0.343045064 */, 18 }, + /* 5194 */ { MAD_F(0x057d792e) /* 0.343133146 */, 18 }, + /* 5195 */ { MAD_F(0x057dd58c) /* 0.343221233 */, 18 }, + /* 5196 */ { MAD_F(0x057e31eb) /* 0.343309326 */, 18 }, + /* 5197 */ { MAD_F(0x057e8e4c) /* 0.343397425 */, 18 }, + /* 5198 */ { MAD_F(0x057eeaae) /* 0.343485529 */, 18 }, + /* 5199 */ { MAD_F(0x057f4712) /* 0.343573639 */, 18 }, + + /* 5200 */ { MAD_F(0x057fa378) /* 0.343661754 */, 18 }, + /* 5201 */ { MAD_F(0x057fffde) /* 0.343749876 */, 18 }, + /* 5202 */ { MAD_F(0x05805c47) /* 0.343838003 */, 18 }, + /* 5203 */ { MAD_F(0x0580b8b1) /* 0.343926135 */, 18 }, + /* 5204 */ { MAD_F(0x0581151c) /* 0.344014273 */, 18 }, + /* 5205 */ { MAD_F(0x05817189) /* 0.344102417 */, 18 }, + /* 5206 */ { MAD_F(0x0581cdf7) /* 0.344190566 */, 18 }, + /* 5207 */ { MAD_F(0x05822a67) /* 0.344278722 */, 18 }, + /* 5208 */ { MAD_F(0x058286d9) /* 0.344366882 */, 18 }, + /* 5209 */ { MAD_F(0x0582e34c) /* 0.344455049 */, 18 }, + /* 5210 */ { MAD_F(0x05833fc0) /* 0.344543221 */, 18 }, + /* 5211 */ { MAD_F(0x05839c36) /* 0.344631398 */, 18 }, + /* 5212 */ { MAD_F(0x0583f8ae) /* 0.344719582 */, 18 }, + /* 5213 */ { MAD_F(0x05845527) /* 0.344807771 */, 18 }, + /* 5214 */ { MAD_F(0x0584b1a1) /* 0.344895965 */, 18 }, + /* 5215 */ { MAD_F(0x05850e1e) /* 0.344984165 */, 18 }, + + /* 5216 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 18 }, + /* 5217 */ { MAD_F(0x0585c71a) /* 0.345160583 */, 18 }, + /* 5218 */ { MAD_F(0x0586239b) /* 0.345248800 */, 18 }, + /* 5219 */ { MAD_F(0x0586801d) /* 0.345337023 */, 18 }, + /* 5220 */ { MAD_F(0x0586dca1) /* 0.345425251 */, 18 }, + /* 5221 */ { MAD_F(0x05873926) /* 0.345513485 */, 18 }, + /* 5222 */ { MAD_F(0x058795ac) /* 0.345601725 */, 18 }, + /* 5223 */ { MAD_F(0x0587f235) /* 0.345689970 */, 18 }, + /* 5224 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 18 }, + /* 5225 */ { MAD_F(0x0588ab49) /* 0.345866478 */, 18 }, + /* 5226 */ { MAD_F(0x058907d6) /* 0.345954740 */, 18 }, + /* 5227 */ { MAD_F(0x05896464) /* 0.346043008 */, 18 }, + /* 5228 */ { MAD_F(0x0589c0f4) /* 0.346131281 */, 18 }, + /* 5229 */ { MAD_F(0x058a1d85) /* 0.346219560 */, 18 }, + /* 5230 */ { MAD_F(0x058a7a18) /* 0.346307845 */, 18 }, + /* 5231 */ { MAD_F(0x058ad6ac) /* 0.346396135 */, 18 }, + + /* 5232 */ { MAD_F(0x058b3342) /* 0.346484431 */, 18 }, + /* 5233 */ { MAD_F(0x058b8fd9) /* 0.346572733 */, 18 }, + /* 5234 */ { MAD_F(0x058bec72) /* 0.346661040 */, 18 }, + /* 5235 */ { MAD_F(0x058c490c) /* 0.346749353 */, 18 }, + /* 5236 */ { MAD_F(0x058ca5a8) /* 0.346837671 */, 18 }, + /* 5237 */ { MAD_F(0x058d0246) /* 0.346925996 */, 18 }, + /* 5238 */ { MAD_F(0x058d5ee4) /* 0.347014325 */, 18 }, + /* 5239 */ { MAD_F(0x058dbb85) /* 0.347102661 */, 18 }, + /* 5240 */ { MAD_F(0x058e1827) /* 0.347191002 */, 18 }, + /* 5241 */ { MAD_F(0x058e74ca) /* 0.347279348 */, 18 }, + /* 5242 */ { MAD_F(0x058ed16f) /* 0.347367700 */, 18 }, + /* 5243 */ { MAD_F(0x058f2e15) /* 0.347456058 */, 18 }, + /* 5244 */ { MAD_F(0x058f8abd) /* 0.347544422 */, 18 }, + /* 5245 */ { MAD_F(0x058fe766) /* 0.347632791 */, 18 }, + /* 5246 */ { MAD_F(0x05904411) /* 0.347721165 */, 18 }, + /* 5247 */ { MAD_F(0x0590a0be) /* 0.347809546 */, 18 }, + + /* 5248 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 18 }, + /* 5249 */ { MAD_F(0x05915a1b) /* 0.347986323 */, 18 }, + /* 5250 */ { MAD_F(0x0591b6cc) /* 0.348074720 */, 18 }, + /* 5251 */ { MAD_F(0x0592137e) /* 0.348163123 */, 18 }, + /* 5252 */ { MAD_F(0x05927032) /* 0.348251531 */, 18 }, + /* 5253 */ { MAD_F(0x0592cce8) /* 0.348339945 */, 18 }, + /* 5254 */ { MAD_F(0x0593299f) /* 0.348428365 */, 18 }, + /* 5255 */ { MAD_F(0x05938657) /* 0.348516790 */, 18 }, + /* 5256 */ { MAD_F(0x0593e311) /* 0.348605221 */, 18 }, + /* 5257 */ { MAD_F(0x05943fcd) /* 0.348693657 */, 18 }, + /* 5258 */ { MAD_F(0x05949c8a) /* 0.348782099 */, 18 }, + /* 5259 */ { MAD_F(0x0594f948) /* 0.348870547 */, 18 }, + /* 5260 */ { MAD_F(0x05955608) /* 0.348959000 */, 18 }, + /* 5261 */ { MAD_F(0x0595b2ca) /* 0.349047459 */, 18 }, + /* 5262 */ { MAD_F(0x05960f8c) /* 0.349135923 */, 18 }, + /* 5263 */ { MAD_F(0x05966c51) /* 0.349224393 */, 18 }, + + /* 5264 */ { MAD_F(0x0596c917) /* 0.349312869 */, 18 }, + /* 5265 */ { MAD_F(0x059725de) /* 0.349401350 */, 18 }, + /* 5266 */ { MAD_F(0x059782a7) /* 0.349489837 */, 18 }, + /* 5267 */ { MAD_F(0x0597df72) /* 0.349578329 */, 18 }, + /* 5268 */ { MAD_F(0x05983c3e) /* 0.349666827 */, 18 }, + /* 5269 */ { MAD_F(0x0598990c) /* 0.349755331 */, 18 }, + /* 5270 */ { MAD_F(0x0598f5db) /* 0.349843840 */, 18 }, + /* 5271 */ { MAD_F(0x059952ab) /* 0.349932355 */, 18 }, + /* 5272 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 18 }, + /* 5273 */ { MAD_F(0x059a0c51) /* 0.350109402 */, 18 }, + /* 5274 */ { MAD_F(0x059a6926) /* 0.350197933 */, 18 }, + /* 5275 */ { MAD_F(0x059ac5fc) /* 0.350286470 */, 18 }, + /* 5276 */ { MAD_F(0x059b22d4) /* 0.350375013 */, 18 }, + /* 5277 */ { MAD_F(0x059b7fae) /* 0.350463562 */, 18 }, + /* 5278 */ { MAD_F(0x059bdc89) /* 0.350552116 */, 18 }, + /* 5279 */ { MAD_F(0x059c3965) /* 0.350640675 */, 18 }, + + /* 5280 */ { MAD_F(0x059c9643) /* 0.350729240 */, 18 }, + /* 5281 */ { MAD_F(0x059cf323) /* 0.350817811 */, 18 }, + /* 5282 */ { MAD_F(0x059d5004) /* 0.350906388 */, 18 }, + /* 5283 */ { MAD_F(0x059dace6) /* 0.350994970 */, 18 }, + /* 5284 */ { MAD_F(0x059e09cb) /* 0.351083557 */, 18 }, + /* 5285 */ { MAD_F(0x059e66b0) /* 0.351172150 */, 18 }, + /* 5286 */ { MAD_F(0x059ec397) /* 0.351260749 */, 18 }, + /* 5287 */ { MAD_F(0x059f2080) /* 0.351349353 */, 18 }, + /* 5288 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 18 }, + /* 5289 */ { MAD_F(0x059fda55) /* 0.351526579 */, 18 }, + /* 5290 */ { MAD_F(0x05a03742) /* 0.351615200 */, 18 }, + /* 5291 */ { MAD_F(0x05a09431) /* 0.351703827 */, 18 }, + /* 5292 */ { MAD_F(0x05a0f121) /* 0.351792459 */, 18 }, + /* 5293 */ { MAD_F(0x05a14e12) /* 0.351881097 */, 18 }, + /* 5294 */ { MAD_F(0x05a1ab05) /* 0.351969740 */, 18 }, + /* 5295 */ { MAD_F(0x05a207fa) /* 0.352058389 */, 18 }, + + /* 5296 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 18 }, + /* 5297 */ { MAD_F(0x05a2c1e7) /* 0.352235704 */, 18 }, + /* 5298 */ { MAD_F(0x05a31ee1) /* 0.352324369 */, 18 }, + /* 5299 */ { MAD_F(0x05a37bdb) /* 0.352413041 */, 18 }, + /* 5300 */ { MAD_F(0x05a3d8d7) /* 0.352501718 */, 18 }, + /* 5301 */ { MAD_F(0x05a435d5) /* 0.352590400 */, 18 }, + /* 5302 */ { MAD_F(0x05a492d4) /* 0.352679088 */, 18 }, + /* 5303 */ { MAD_F(0x05a4efd4) /* 0.352767782 */, 18 }, + /* 5304 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 18 }, + /* 5305 */ { MAD_F(0x05a5a9da) /* 0.352945186 */, 18 }, + /* 5306 */ { MAD_F(0x05a606df) /* 0.353033896 */, 18 }, + /* 5307 */ { MAD_F(0x05a663e5) /* 0.353122612 */, 18 }, + /* 5308 */ { MAD_F(0x05a6c0ed) /* 0.353211333 */, 18 }, + /* 5309 */ { MAD_F(0x05a71df7) /* 0.353300061 */, 18 }, + /* 5310 */ { MAD_F(0x05a77b02) /* 0.353388793 */, 18 }, + /* 5311 */ { MAD_F(0x05a7d80e) /* 0.353477531 */, 18 }, + + /* 5312 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 18 }, + /* 5313 */ { MAD_F(0x05a8922c) /* 0.353655024 */, 18 }, + /* 5314 */ { MAD_F(0x05a8ef3c) /* 0.353743779 */, 18 }, + /* 5315 */ { MAD_F(0x05a94c4f) /* 0.353832540 */, 18 }, + /* 5316 */ { MAD_F(0x05a9a963) /* 0.353921306 */, 18 }, + /* 5317 */ { MAD_F(0x05aa0678) /* 0.354010077 */, 18 }, + /* 5318 */ { MAD_F(0x05aa638f) /* 0.354098855 */, 18 }, + /* 5319 */ { MAD_F(0x05aac0a8) /* 0.354187637 */, 18 }, + /* 5320 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 18 }, + /* 5321 */ { MAD_F(0x05ab7add) /* 0.354365220 */, 18 }, + /* 5322 */ { MAD_F(0x05abd7fa) /* 0.354454019 */, 18 }, + /* 5323 */ { MAD_F(0x05ac3518) /* 0.354542824 */, 18 }, + /* 5324 */ { MAD_F(0x05ac9238) /* 0.354631635 */, 18 }, + /* 5325 */ { MAD_F(0x05acef5a) /* 0.354720451 */, 18 }, + /* 5326 */ { MAD_F(0x05ad4c7d) /* 0.354809272 */, 18 }, + /* 5327 */ { MAD_F(0x05ada9a1) /* 0.354898100 */, 18 }, + + /* 5328 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 18 }, + /* 5329 */ { MAD_F(0x05ae63ee) /* 0.355075771 */, 18 }, + /* 5330 */ { MAD_F(0x05aec117) /* 0.355164615 */, 18 }, + /* 5331 */ { MAD_F(0x05af1e41) /* 0.355253464 */, 18 }, + /* 5332 */ { MAD_F(0x05af7b6d) /* 0.355342319 */, 18 }, + /* 5333 */ { MAD_F(0x05afd89b) /* 0.355431180 */, 18 }, + /* 5334 */ { MAD_F(0x05b035c9) /* 0.355520046 */, 18 }, + /* 5335 */ { MAD_F(0x05b092fa) /* 0.355608917 */, 18 }, + /* 5336 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 18 }, + /* 5337 */ { MAD_F(0x05b14d5f) /* 0.355786677 */, 18 }, + /* 5338 */ { MAD_F(0x05b1aa94) /* 0.355875566 */, 18 }, + /* 5339 */ { MAD_F(0x05b207ca) /* 0.355964460 */, 18 }, + /* 5340 */ { MAD_F(0x05b26502) /* 0.356053359 */, 18 }, + /* 5341 */ { MAD_F(0x05b2c23b) /* 0.356142264 */, 18 }, + /* 5342 */ { MAD_F(0x05b31f76) /* 0.356231175 */, 18 }, + /* 5343 */ { MAD_F(0x05b37cb2) /* 0.356320091 */, 18 }, + + /* 5344 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 18 }, + /* 5345 */ { MAD_F(0x05b4372f) /* 0.356497940 */, 18 }, + /* 5346 */ { MAD_F(0x05b4946f) /* 0.356586872 */, 18 }, + /* 5347 */ { MAD_F(0x05b4f1b2) /* 0.356675811 */, 18 }, + /* 5348 */ { MAD_F(0x05b54ef5) /* 0.356764754 */, 18 }, + /* 5349 */ { MAD_F(0x05b5ac3a) /* 0.356853704 */, 18 }, + /* 5350 */ { MAD_F(0x05b60981) /* 0.356942659 */, 18 }, + /* 5351 */ { MAD_F(0x05b666c9) /* 0.357031619 */, 18 }, + /* 5352 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 18 }, + /* 5353 */ { MAD_F(0x05b7215e) /* 0.357209557 */, 18 }, + /* 5354 */ { MAD_F(0x05b77eab) /* 0.357298534 */, 18 }, + /* 5355 */ { MAD_F(0x05b7dbf9) /* 0.357387516 */, 18 }, + /* 5356 */ { MAD_F(0x05b83948) /* 0.357476504 */, 18 }, + /* 5357 */ { MAD_F(0x05b89699) /* 0.357565498 */, 18 }, + /* 5358 */ { MAD_F(0x05b8f3ec) /* 0.357654497 */, 18 }, + /* 5359 */ { MAD_F(0x05b95140) /* 0.357743502 */, 18 }, + + /* 5360 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 18 }, + /* 5361 */ { MAD_F(0x05ba0bec) /* 0.357921528 */, 18 }, + /* 5362 */ { MAD_F(0x05ba6945) /* 0.358010550 */, 18 }, + /* 5363 */ { MAD_F(0x05bac69f) /* 0.358099576 */, 18 }, + /* 5364 */ { MAD_F(0x05bb23fa) /* 0.358188609 */, 18 }, + /* 5365 */ { MAD_F(0x05bb8157) /* 0.358277647 */, 18 }, + /* 5366 */ { MAD_F(0x05bbdeb6) /* 0.358366690 */, 18 }, + /* 5367 */ { MAD_F(0x05bc3c16) /* 0.358455739 */, 18 }, + /* 5368 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 18 }, + /* 5369 */ { MAD_F(0x05bcf6da) /* 0.358633854 */, 18 }, + /* 5370 */ { MAD_F(0x05bd543e) /* 0.358722920 */, 18 }, + /* 5371 */ { MAD_F(0x05bdb1a4) /* 0.358811991 */, 18 }, + /* 5372 */ { MAD_F(0x05be0f0b) /* 0.358901067 */, 18 }, + /* 5373 */ { MAD_F(0x05be6c74) /* 0.358990150 */, 18 }, + /* 5374 */ { MAD_F(0x05bec9df) /* 0.359079237 */, 18 }, + /* 5375 */ { MAD_F(0x05bf274a) /* 0.359168331 */, 18 }, + + /* 5376 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 18 }, + /* 5377 */ { MAD_F(0x05bfe226) /* 0.359346534 */, 18 }, + /* 5378 */ { MAD_F(0x05c03f97) /* 0.359435644 */, 18 }, + /* 5379 */ { MAD_F(0x05c09d08) /* 0.359524759 */, 18 }, + /* 5380 */ { MAD_F(0x05c0fa7c) /* 0.359613880 */, 18 }, + /* 5381 */ { MAD_F(0x05c157f0) /* 0.359703006 */, 18 }, + /* 5382 */ { MAD_F(0x05c1b566) /* 0.359792138 */, 18 }, + /* 5383 */ { MAD_F(0x05c212de) /* 0.359881276 */, 18 }, + /* 5384 */ { MAD_F(0x05c27057) /* 0.359970419 */, 18 }, + /* 5385 */ { MAD_F(0x05c2cdd2) /* 0.360059567 */, 18 }, + /* 5386 */ { MAD_F(0x05c32b4e) /* 0.360148721 */, 18 }, + /* 5387 */ { MAD_F(0x05c388cb) /* 0.360237881 */, 18 }, + /* 5388 */ { MAD_F(0x05c3e64b) /* 0.360327046 */, 18 }, + /* 5389 */ { MAD_F(0x05c443cb) /* 0.360416216 */, 18 }, + /* 5390 */ { MAD_F(0x05c4a14d) /* 0.360505392 */, 18 }, + /* 5391 */ { MAD_F(0x05c4fed1) /* 0.360594574 */, 18 }, + + /* 5392 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 18 }, + /* 5393 */ { MAD_F(0x05c5b9dc) /* 0.360772953 */, 18 }, + /* 5394 */ { MAD_F(0x05c61764) /* 0.360862152 */, 18 }, + /* 5395 */ { MAD_F(0x05c674ed) /* 0.360951355 */, 18 }, + /* 5396 */ { MAD_F(0x05c6d278) /* 0.361040564 */, 18 }, + /* 5397 */ { MAD_F(0x05c73005) /* 0.361129779 */, 18 }, + /* 5398 */ { MAD_F(0x05c78d93) /* 0.361218999 */, 18 }, + /* 5399 */ { MAD_F(0x05c7eb22) /* 0.361308225 */, 18 }, + /* 5400 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 18 }, + /* 5401 */ { MAD_F(0x05c8a645) /* 0.361486693 */, 18 }, + /* 5402 */ { MAD_F(0x05c903d9) /* 0.361575935 */, 18 }, + /* 5403 */ { MAD_F(0x05c9616e) /* 0.361665183 */, 18 }, + /* 5404 */ { MAD_F(0x05c9bf05) /* 0.361754436 */, 18 }, + /* 5405 */ { MAD_F(0x05ca1c9d) /* 0.361843695 */, 18 }, + /* 5406 */ { MAD_F(0x05ca7a37) /* 0.361932959 */, 18 }, + /* 5407 */ { MAD_F(0x05cad7d2) /* 0.362022229 */, 18 }, + + /* 5408 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 18 }, + /* 5409 */ { MAD_F(0x05cb930d) /* 0.362200785 */, 18 }, + /* 5410 */ { MAD_F(0x05cbf0ac) /* 0.362290071 */, 18 }, + /* 5411 */ { MAD_F(0x05cc4e4d) /* 0.362379362 */, 18 }, + /* 5412 */ { MAD_F(0x05ccabf0) /* 0.362468660 */, 18 }, + /* 5413 */ { MAD_F(0x05cd0994) /* 0.362557962 */, 18 }, + /* 5414 */ { MAD_F(0x05cd6739) /* 0.362647271 */, 18 }, + /* 5415 */ { MAD_F(0x05cdc4e0) /* 0.362736584 */, 18 }, + /* 5416 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 18 }, + /* 5417 */ { MAD_F(0x05ce8033) /* 0.362915228 */, 18 }, + /* 5418 */ { MAD_F(0x05ceddde) /* 0.363004559 */, 18 }, + /* 5419 */ { MAD_F(0x05cf3b8b) /* 0.363093894 */, 18 }, + /* 5420 */ { MAD_F(0x05cf9939) /* 0.363183236 */, 18 }, + /* 5421 */ { MAD_F(0x05cff6e9) /* 0.363272582 */, 18 }, + /* 5422 */ { MAD_F(0x05d0549a) /* 0.363361935 */, 18 }, + /* 5423 */ { MAD_F(0x05d0b24d) /* 0.363451292 */, 18 }, + + /* 5424 */ { MAD_F(0x05d11001) /* 0.363540655 */, 18 }, + /* 5425 */ { MAD_F(0x05d16db7) /* 0.363630024 */, 18 }, + /* 5426 */ { MAD_F(0x05d1cb6e) /* 0.363719398 */, 18 }, + /* 5427 */ { MAD_F(0x05d22927) /* 0.363808778 */, 18 }, + /* 5428 */ { MAD_F(0x05d286e1) /* 0.363898163 */, 18 }, + /* 5429 */ { MAD_F(0x05d2e49d) /* 0.363987554 */, 18 }, + /* 5430 */ { MAD_F(0x05d3425a) /* 0.364076950 */, 18 }, + /* 5431 */ { MAD_F(0x05d3a018) /* 0.364166352 */, 18 }, + /* 5432 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 18 }, + /* 5433 */ { MAD_F(0x05d45b9a) /* 0.364345171 */, 18 }, + /* 5434 */ { MAD_F(0x05d4b95d) /* 0.364434589 */, 18 }, + /* 5435 */ { MAD_F(0x05d51721) /* 0.364524013 */, 18 }, + /* 5436 */ { MAD_F(0x05d574e7) /* 0.364613442 */, 18 }, + /* 5437 */ { MAD_F(0x05d5d2af) /* 0.364702877 */, 18 }, + /* 5438 */ { MAD_F(0x05d63078) /* 0.364792317 */, 18 }, + /* 5439 */ { MAD_F(0x05d68e42) /* 0.364881762 */, 18 }, + + /* 5440 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 18 }, + /* 5441 */ { MAD_F(0x05d749db) /* 0.365060669 */, 18 }, + /* 5442 */ { MAD_F(0x05d7a7aa) /* 0.365150131 */, 18 }, + /* 5443 */ { MAD_F(0x05d8057a) /* 0.365239599 */, 18 }, + /* 5444 */ { MAD_F(0x05d8634c) /* 0.365329072 */, 18 }, + /* 5445 */ { MAD_F(0x05d8c11f) /* 0.365418550 */, 18 }, + /* 5446 */ { MAD_F(0x05d91ef4) /* 0.365508034 */, 18 }, + /* 5447 */ { MAD_F(0x05d97cca) /* 0.365597523 */, 18 }, + /* 5448 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 18 }, + /* 5449 */ { MAD_F(0x05da387a) /* 0.365776518 */, 18 }, + /* 5450 */ { MAD_F(0x05da9655) /* 0.365866024 */, 18 }, + /* 5451 */ { MAD_F(0x05daf431) /* 0.365955536 */, 18 }, + /* 5452 */ { MAD_F(0x05db520e) /* 0.366045052 */, 18 }, + /* 5453 */ { MAD_F(0x05dbafed) /* 0.366134574 */, 18 }, + /* 5454 */ { MAD_F(0x05dc0dce) /* 0.366224102 */, 18 }, + /* 5455 */ { MAD_F(0x05dc6baf) /* 0.366313635 */, 18 }, + + /* 5456 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 18 }, + /* 5457 */ { MAD_F(0x05dd2778) /* 0.366492718 */, 18 }, + /* 5458 */ { MAD_F(0x05dd855e) /* 0.366582267 */, 18 }, + /* 5459 */ { MAD_F(0x05dde346) /* 0.366671822 */, 18 }, + /* 5460 */ { MAD_F(0x05de412f) /* 0.366761383 */, 18 }, + /* 5461 */ { MAD_F(0x05de9f1a) /* 0.366850949 */, 18 }, + /* 5462 */ { MAD_F(0x05defd06) /* 0.366940520 */, 18 }, + /* 5463 */ { MAD_F(0x05df5af3) /* 0.367030097 */, 18 }, + /* 5464 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 18 }, + /* 5465 */ { MAD_F(0x05e016d3) /* 0.367209267 */, 18 }, + /* 5466 */ { MAD_F(0x05e074c5) /* 0.367298861 */, 18 }, + /* 5467 */ { MAD_F(0x05e0d2b8) /* 0.367388459 */, 18 }, + /* 5468 */ { MAD_F(0x05e130ad) /* 0.367478064 */, 18 }, + /* 5469 */ { MAD_F(0x05e18ea4) /* 0.367567673 */, 18 }, + /* 5470 */ { MAD_F(0x05e1ec9c) /* 0.367657288 */, 18 }, + /* 5471 */ { MAD_F(0x05e24a95) /* 0.367746909 */, 18 }, + + /* 5472 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 18 }, + /* 5473 */ { MAD_F(0x05e3068c) /* 0.367926167 */, 18 }, + /* 5474 */ { MAD_F(0x05e3648a) /* 0.368015804 */, 18 }, + /* 5475 */ { MAD_F(0x05e3c289) /* 0.368105446 */, 18 }, + /* 5476 */ { MAD_F(0x05e4208a) /* 0.368195094 */, 18 }, + /* 5477 */ { MAD_F(0x05e47e8c) /* 0.368284747 */, 18 }, + /* 5478 */ { MAD_F(0x05e4dc8f) /* 0.368374406 */, 18 }, + /* 5479 */ { MAD_F(0x05e53a94) /* 0.368464070 */, 18 }, + /* 5480 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 18 }, + /* 5481 */ { MAD_F(0x05e5f6a3) /* 0.368643415 */, 18 }, + /* 5482 */ { MAD_F(0x05e654ac) /* 0.368733096 */, 18 }, + /* 5483 */ { MAD_F(0x05e6b2b7) /* 0.368822782 */, 18 }, + /* 5484 */ { MAD_F(0x05e710c4) /* 0.368912473 */, 18 }, + /* 5485 */ { MAD_F(0x05e76ed2) /* 0.369002170 */, 18 }, + /* 5486 */ { MAD_F(0x05e7cce1) /* 0.369091873 */, 18 }, + /* 5487 */ { MAD_F(0x05e82af2) /* 0.369181581 */, 18 }, + + /* 5488 */ { MAD_F(0x05e88904) /* 0.369271294 */, 18 }, + /* 5489 */ { MAD_F(0x05e8e718) /* 0.369361013 */, 18 }, + /* 5490 */ { MAD_F(0x05e9452d) /* 0.369450737 */, 18 }, + /* 5491 */ { MAD_F(0x05e9a343) /* 0.369540467 */, 18 }, + /* 5492 */ { MAD_F(0x05ea015c) /* 0.369630202 */, 18 }, + /* 5493 */ { MAD_F(0x05ea5f75) /* 0.369719942 */, 18 }, + /* 5494 */ { MAD_F(0x05eabd90) /* 0.369809688 */, 18 }, + /* 5495 */ { MAD_F(0x05eb1bad) /* 0.369899440 */, 18 }, + /* 5496 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 18 }, + /* 5497 */ { MAD_F(0x05ebd7ea) /* 0.370078959 */, 18 }, + /* 5498 */ { MAD_F(0x05ec360b) /* 0.370168727 */, 18 }, + /* 5499 */ { MAD_F(0x05ec942d) /* 0.370258500 */, 18 }, + /* 5500 */ { MAD_F(0x05ecf251) /* 0.370348279 */, 18 }, + /* 5501 */ { MAD_F(0x05ed5076) /* 0.370438063 */, 18 }, + /* 5502 */ { MAD_F(0x05edae9d) /* 0.370527853 */, 18 }, + /* 5503 */ { MAD_F(0x05ee0cc5) /* 0.370617648 */, 18 }, + + /* 5504 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 18 }, + /* 5505 */ { MAD_F(0x05eec91a) /* 0.370797254 */, 18 }, + /* 5506 */ { MAD_F(0x05ef2746) /* 0.370887065 */, 18 }, + /* 5507 */ { MAD_F(0x05ef8574) /* 0.370976882 */, 18 }, + /* 5508 */ { MAD_F(0x05efe3a4) /* 0.371066704 */, 18 }, + /* 5509 */ { MAD_F(0x05f041d5) /* 0.371156532 */, 18 }, + /* 5510 */ { MAD_F(0x05f0a007) /* 0.371246365 */, 18 }, + /* 5511 */ { MAD_F(0x05f0fe3b) /* 0.371336203 */, 18 }, + /* 5512 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 18 }, + /* 5513 */ { MAD_F(0x05f1baa7) /* 0.371515897 */, 18 }, + /* 5514 */ { MAD_F(0x05f218df) /* 0.371605751 */, 18 }, + /* 5515 */ { MAD_F(0x05f27719) /* 0.371695612 */, 18 }, + /* 5516 */ { MAD_F(0x05f2d554) /* 0.371785477 */, 18 }, + /* 5517 */ { MAD_F(0x05f33390) /* 0.371875348 */, 18 }, + /* 5518 */ { MAD_F(0x05f391cf) /* 0.371965225 */, 18 }, + /* 5519 */ { MAD_F(0x05f3f00e) /* 0.372055107 */, 18 }, + + /* 5520 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 18 }, + /* 5521 */ { MAD_F(0x05f4ac91) /* 0.372234887 */, 18 }, + /* 5522 */ { MAD_F(0x05f50ad5) /* 0.372324785 */, 18 }, + /* 5523 */ { MAD_F(0x05f5691b) /* 0.372414689 */, 18 }, + /* 5524 */ { MAD_F(0x05f5c761) /* 0.372504598 */, 18 }, + /* 5525 */ { MAD_F(0x05f625aa) /* 0.372594513 */, 18 }, + /* 5526 */ { MAD_F(0x05f683f3) /* 0.372684433 */, 18 }, + /* 5527 */ { MAD_F(0x05f6e23f) /* 0.372774358 */, 18 }, + /* 5528 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 18 }, + /* 5529 */ { MAD_F(0x05f79ed9) /* 0.372954225 */, 18 }, + /* 5530 */ { MAD_F(0x05f7fd29) /* 0.373044167 */, 18 }, + /* 5531 */ { MAD_F(0x05f85b7a) /* 0.373134114 */, 18 }, + /* 5532 */ { MAD_F(0x05f8b9cc) /* 0.373224066 */, 18 }, + /* 5533 */ { MAD_F(0x05f91820) /* 0.373314024 */, 18 }, + /* 5534 */ { MAD_F(0x05f97675) /* 0.373403987 */, 18 }, + /* 5535 */ { MAD_F(0x05f9d4cc) /* 0.373493956 */, 18 }, + + /* 5536 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 18 }, + /* 5537 */ { MAD_F(0x05fa917e) /* 0.373673910 */, 18 }, + /* 5538 */ { MAD_F(0x05faefd9) /* 0.373763895 */, 18 }, + /* 5539 */ { MAD_F(0x05fb4e36) /* 0.373853885 */, 18 }, + /* 5540 */ { MAD_F(0x05fbac94) /* 0.373943881 */, 18 }, + /* 5541 */ { MAD_F(0x05fc0af3) /* 0.374033882 */, 18 }, + /* 5542 */ { MAD_F(0x05fc6954) /* 0.374123889 */, 18 }, + /* 5543 */ { MAD_F(0x05fcc7b7) /* 0.374213901 */, 18 }, + /* 5544 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 18 }, + /* 5545 */ { MAD_F(0x05fd8480) /* 0.374393941 */, 18 }, + /* 5546 */ { MAD_F(0x05fde2e7) /* 0.374483970 */, 18 }, + /* 5547 */ { MAD_F(0x05fe414f) /* 0.374574003 */, 18 }, + /* 5548 */ { MAD_F(0x05fe9fb9) /* 0.374664042 */, 18 }, + /* 5549 */ { MAD_F(0x05fefe24) /* 0.374754087 */, 18 }, + /* 5550 */ { MAD_F(0x05ff5c91) /* 0.374844137 */, 18 }, + /* 5551 */ { MAD_F(0x05ffbaff) /* 0.374934192 */, 18 }, + + /* 5552 */ { MAD_F(0x0600196e) /* 0.375024253 */, 18 }, + /* 5553 */ { MAD_F(0x060077df) /* 0.375114319 */, 18 }, + /* 5554 */ { MAD_F(0x0600d651) /* 0.375204391 */, 18 }, + /* 5555 */ { MAD_F(0x060134c5) /* 0.375294468 */, 18 }, + /* 5556 */ { MAD_F(0x0601933b) /* 0.375384550 */, 18 }, + /* 5557 */ { MAD_F(0x0601f1b1) /* 0.375474638 */, 18 }, + /* 5558 */ { MAD_F(0x0602502a) /* 0.375564731 */, 18 }, + /* 5559 */ { MAD_F(0x0602aea3) /* 0.375654830 */, 18 }, + /* 5560 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 18 }, + /* 5561 */ { MAD_F(0x06036b9b) /* 0.375835043 */, 18 }, + /* 5562 */ { MAD_F(0x0603ca19) /* 0.375925158 */, 18 }, + /* 5563 */ { MAD_F(0x06042898) /* 0.376015278 */, 18 }, + /* 5564 */ { MAD_F(0x06048719) /* 0.376105404 */, 18 }, + /* 5565 */ { MAD_F(0x0604e59c) /* 0.376195535 */, 18 }, + /* 5566 */ { MAD_F(0x0605441f) /* 0.376285671 */, 18 }, + /* 5567 */ { MAD_F(0x0605a2a5) /* 0.376375813 */, 18 }, + + /* 5568 */ { MAD_F(0x0606012b) /* 0.376465960 */, 18 }, + /* 5569 */ { MAD_F(0x06065fb4) /* 0.376556113 */, 18 }, + /* 5570 */ { MAD_F(0x0606be3d) /* 0.376646271 */, 18 }, + /* 5571 */ { MAD_F(0x06071cc8) /* 0.376736434 */, 18 }, + /* 5572 */ { MAD_F(0x06077b55) /* 0.376826603 */, 18 }, + /* 5573 */ { MAD_F(0x0607d9e3) /* 0.376916777 */, 18 }, + /* 5574 */ { MAD_F(0x06083872) /* 0.377006957 */, 18 }, + /* 5575 */ { MAD_F(0x06089703) /* 0.377097141 */, 18 }, + /* 5576 */ { MAD_F(0x0608f595) /* 0.377187332 */, 18 }, + /* 5577 */ { MAD_F(0x06095429) /* 0.377277528 */, 18 }, + /* 5578 */ { MAD_F(0x0609b2be) /* 0.377367729 */, 18 }, + /* 5579 */ { MAD_F(0x060a1155) /* 0.377457935 */, 18 }, + /* 5580 */ { MAD_F(0x060a6fed) /* 0.377548147 */, 18 }, + /* 5581 */ { MAD_F(0x060ace86) /* 0.377638364 */, 18 }, + /* 5582 */ { MAD_F(0x060b2d21) /* 0.377728587 */, 18 }, + /* 5583 */ { MAD_F(0x060b8bbe) /* 0.377818815 */, 18 }, + + /* 5584 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 18 }, + /* 5585 */ { MAD_F(0x060c48fb) /* 0.377999288 */, 18 }, + /* 5586 */ { MAD_F(0x060ca79c) /* 0.378089532 */, 18 }, + /* 5587 */ { MAD_F(0x060d063e) /* 0.378179781 */, 18 }, + /* 5588 */ { MAD_F(0x060d64e1) /* 0.378270036 */, 18 }, + /* 5589 */ { MAD_F(0x060dc387) /* 0.378360297 */, 18 }, + /* 5590 */ { MAD_F(0x060e222d) /* 0.378450563 */, 18 }, + /* 5591 */ { MAD_F(0x060e80d5) /* 0.378540834 */, 18 }, + /* 5592 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 18 }, + /* 5593 */ { MAD_F(0x060f3e29) /* 0.378721392 */, 18 }, + /* 5594 */ { MAD_F(0x060f9cd6) /* 0.378811680 */, 18 }, + /* 5595 */ { MAD_F(0x060ffb83) /* 0.378901972 */, 18 }, + /* 5596 */ { MAD_F(0x06105a33) /* 0.378992270 */, 18 }, + /* 5597 */ { MAD_F(0x0610b8e3) /* 0.379082574 */, 18 }, + /* 5598 */ { MAD_F(0x06111795) /* 0.379172883 */, 18 }, + /* 5599 */ { MAD_F(0x06117649) /* 0.379263197 */, 18 }, + + /* 5600 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 18 }, + /* 5601 */ { MAD_F(0x061233b4) /* 0.379443841 */, 18 }, + /* 5602 */ { MAD_F(0x0612926c) /* 0.379534172 */, 18 }, + /* 5603 */ { MAD_F(0x0612f125) /* 0.379624507 */, 18 }, + /* 5604 */ { MAD_F(0x06134fe0) /* 0.379714848 */, 18 }, + /* 5605 */ { MAD_F(0x0613ae9c) /* 0.379805195 */, 18 }, + /* 5606 */ { MAD_F(0x06140d5a) /* 0.379895547 */, 18 }, + /* 5607 */ { MAD_F(0x06146c19) /* 0.379985904 */, 18 }, + /* 5608 */ { MAD_F(0x0614cada) /* 0.380076266 */, 18 }, + /* 5609 */ { MAD_F(0x0615299c) /* 0.380166634 */, 18 }, + /* 5610 */ { MAD_F(0x0615885f) /* 0.380257008 */, 18 }, + /* 5611 */ { MAD_F(0x0615e724) /* 0.380347386 */, 18 }, + /* 5612 */ { MAD_F(0x061645ea) /* 0.380437770 */, 18 }, + /* 5613 */ { MAD_F(0x0616a4b2) /* 0.380528160 */, 18 }, + /* 5614 */ { MAD_F(0x0617037b) /* 0.380618555 */, 18 }, + /* 5615 */ { MAD_F(0x06176246) /* 0.380708955 */, 18 }, + + /* 5616 */ { MAD_F(0x0617c112) /* 0.380799360 */, 18 }, + /* 5617 */ { MAD_F(0x06181fdf) /* 0.380889771 */, 18 }, + /* 5618 */ { MAD_F(0x06187eae) /* 0.380980187 */, 18 }, + /* 5619 */ { MAD_F(0x0618dd7e) /* 0.381070609 */, 18 }, + /* 5620 */ { MAD_F(0x06193c50) /* 0.381161036 */, 18 }, + /* 5621 */ { MAD_F(0x06199b24) /* 0.381251468 */, 18 }, + /* 5622 */ { MAD_F(0x0619f9f8) /* 0.381341906 */, 18 }, + /* 5623 */ { MAD_F(0x061a58ce) /* 0.381432349 */, 18 }, + /* 5624 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 18 }, + /* 5625 */ { MAD_F(0x061b167f) /* 0.381613251 */, 18 }, + /* 5626 */ { MAD_F(0x061b7559) /* 0.381703711 */, 18 }, + /* 5627 */ { MAD_F(0x061bd435) /* 0.381794175 */, 18 }, + /* 5628 */ { MAD_F(0x061c3313) /* 0.381884645 */, 18 }, + /* 5629 */ { MAD_F(0x061c91f1) /* 0.381975120 */, 18 }, + /* 5630 */ { MAD_F(0x061cf0d2) /* 0.382065601 */, 18 }, + /* 5631 */ { MAD_F(0x061d4fb3) /* 0.382156087 */, 18 }, + + /* 5632 */ { MAD_F(0x061dae96) /* 0.382246578 */, 18 }, + /* 5633 */ { MAD_F(0x061e0d7b) /* 0.382337075 */, 18 }, + /* 5634 */ { MAD_F(0x061e6c61) /* 0.382427577 */, 18 }, + /* 5635 */ { MAD_F(0x061ecb48) /* 0.382518084 */, 18 }, + /* 5636 */ { MAD_F(0x061f2a31) /* 0.382608597 */, 18 }, + /* 5637 */ { MAD_F(0x061f891b) /* 0.382699115 */, 18 }, + /* 5638 */ { MAD_F(0x061fe807) /* 0.382789638 */, 18 }, + /* 5639 */ { MAD_F(0x062046f4) /* 0.382880167 */, 18 }, + /* 5640 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 18 }, + /* 5641 */ { MAD_F(0x062104d3) /* 0.383061241 */, 18 }, + /* 5642 */ { MAD_F(0x062163c4) /* 0.383151786 */, 18 }, + /* 5643 */ { MAD_F(0x0621c2b7) /* 0.383242336 */, 18 }, + /* 5644 */ { MAD_F(0x062221ab) /* 0.383332891 */, 18 }, + /* 5645 */ { MAD_F(0x062280a1) /* 0.383423452 */, 18 }, + /* 5646 */ { MAD_F(0x0622df98) /* 0.383514018 */, 18 }, + /* 5647 */ { MAD_F(0x06233e91) /* 0.383604590 */, 18 }, + + /* 5648 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 18 }, + /* 5649 */ { MAD_F(0x0623fc86) /* 0.383785749 */, 18 }, + /* 5650 */ { MAD_F(0x06245b83) /* 0.383876337 */, 18 }, + /* 5651 */ { MAD_F(0x0624ba82) /* 0.383966930 */, 18 }, + /* 5652 */ { MAD_F(0x06251981) /* 0.384057528 */, 18 }, + /* 5653 */ { MAD_F(0x06257883) /* 0.384148132 */, 18 }, + /* 5654 */ { MAD_F(0x0625d785) /* 0.384238741 */, 18 }, + /* 5655 */ { MAD_F(0x06263689) /* 0.384329355 */, 18 }, + /* 5656 */ { MAD_F(0x0626958f) /* 0.384419975 */, 18 }, + /* 5657 */ { MAD_F(0x0626f496) /* 0.384510600 */, 18 }, + /* 5658 */ { MAD_F(0x0627539e) /* 0.384601230 */, 18 }, + /* 5659 */ { MAD_F(0x0627b2a8) /* 0.384691866 */, 18 }, + /* 5660 */ { MAD_F(0x062811b3) /* 0.384782507 */, 18 }, + /* 5661 */ { MAD_F(0x062870c0) /* 0.384873153 */, 18 }, + /* 5662 */ { MAD_F(0x0628cfce) /* 0.384963805 */, 18 }, + /* 5663 */ { MAD_F(0x06292ede) /* 0.385054462 */, 18 }, + + /* 5664 */ { MAD_F(0x06298def) /* 0.385145124 */, 18 }, + /* 5665 */ { MAD_F(0x0629ed01) /* 0.385235792 */, 18 }, + /* 5666 */ { MAD_F(0x062a4c15) /* 0.385326465 */, 18 }, + /* 5667 */ { MAD_F(0x062aab2a) /* 0.385417143 */, 18 }, + /* 5668 */ { MAD_F(0x062b0a41) /* 0.385507827 */, 18 }, + /* 5669 */ { MAD_F(0x062b6959) /* 0.385598516 */, 18 }, + /* 5670 */ { MAD_F(0x062bc873) /* 0.385689211 */, 18 }, + /* 5671 */ { MAD_F(0x062c278e) /* 0.385779910 */, 18 }, + /* 5672 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 18 }, + /* 5673 */ { MAD_F(0x062ce5c8) /* 0.385961326 */, 18 }, + /* 5674 */ { MAD_F(0x062d44e8) /* 0.386052041 */, 18 }, + /* 5675 */ { MAD_F(0x062da408) /* 0.386142762 */, 18 }, + /* 5676 */ { MAD_F(0x062e032a) /* 0.386233489 */, 18 }, + /* 5677 */ { MAD_F(0x062e624e) /* 0.386324221 */, 18 }, + /* 5678 */ { MAD_F(0x062ec173) /* 0.386414958 */, 18 }, + /* 5679 */ { MAD_F(0x062f209a) /* 0.386505700 */, 18 }, + + /* 5680 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 18 }, + /* 5681 */ { MAD_F(0x062fdeeb) /* 0.386687201 */, 18 }, + /* 5682 */ { MAD_F(0x06303e16) /* 0.386777959 */, 18 }, + /* 5683 */ { MAD_F(0x06309d42) /* 0.386868723 */, 18 }, + /* 5684 */ { MAD_F(0x0630fc6f) /* 0.386959492 */, 18 }, + /* 5685 */ { MAD_F(0x06315b9e) /* 0.387050266 */, 18 }, + /* 5686 */ { MAD_F(0x0631bacf) /* 0.387141045 */, 18 }, + /* 5687 */ { MAD_F(0x06321a01) /* 0.387231830 */, 18 }, + /* 5688 */ { MAD_F(0x06327934) /* 0.387322621 */, 18 }, + /* 5689 */ { MAD_F(0x0632d869) /* 0.387413416 */, 18 }, + /* 5690 */ { MAD_F(0x0633379f) /* 0.387504217 */, 18 }, + /* 5691 */ { MAD_F(0x063396d7) /* 0.387595023 */, 18 }, + /* 5692 */ { MAD_F(0x0633f610) /* 0.387685835 */, 18 }, + /* 5693 */ { MAD_F(0x0634554a) /* 0.387776652 */, 18 }, + /* 5694 */ { MAD_F(0x0634b486) /* 0.387867474 */, 18 }, + /* 5695 */ { MAD_F(0x063513c3) /* 0.387958301 */, 18 }, + + /* 5696 */ { MAD_F(0x06357302) /* 0.388049134 */, 18 }, + /* 5697 */ { MAD_F(0x0635d242) /* 0.388139972 */, 18 }, + /* 5698 */ { MAD_F(0x06363184) /* 0.388230816 */, 18 }, + /* 5699 */ { MAD_F(0x063690c7) /* 0.388321665 */, 18 }, + /* 5700 */ { MAD_F(0x0636f00b) /* 0.388412519 */, 18 }, + /* 5701 */ { MAD_F(0x06374f51) /* 0.388503378 */, 18 }, + /* 5702 */ { MAD_F(0x0637ae99) /* 0.388594243 */, 18 }, + /* 5703 */ { MAD_F(0x06380de1) /* 0.388685113 */, 18 }, + /* 5704 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 18 }, + /* 5705 */ { MAD_F(0x0638cc77) /* 0.388866869 */, 18 }, + /* 5706 */ { MAD_F(0x06392bc4) /* 0.388957755 */, 18 }, + /* 5707 */ { MAD_F(0x06398b12) /* 0.389048646 */, 18 }, + /* 5708 */ { MAD_F(0x0639ea62) /* 0.389139542 */, 18 }, + /* 5709 */ { MAD_F(0x063a49b4) /* 0.389230444 */, 18 }, + /* 5710 */ { MAD_F(0x063aa906) /* 0.389321352 */, 18 }, + /* 5711 */ { MAD_F(0x063b085a) /* 0.389412264 */, 18 }, + + /* 5712 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 18 }, + /* 5713 */ { MAD_F(0x063bc707) /* 0.389594105 */, 18 }, + /* 5714 */ { MAD_F(0x063c265f) /* 0.389685033 */, 18 }, + /* 5715 */ { MAD_F(0x063c85b9) /* 0.389775967 */, 18 }, + /* 5716 */ { MAD_F(0x063ce514) /* 0.389866906 */, 18 }, + /* 5717 */ { MAD_F(0x063d4471) /* 0.389957850 */, 18 }, + /* 5718 */ { MAD_F(0x063da3cf) /* 0.390048800 */, 18 }, + /* 5719 */ { MAD_F(0x063e032f) /* 0.390139755 */, 18 }, + /* 5720 */ { MAD_F(0x063e6290) /* 0.390230715 */, 18 }, + /* 5721 */ { MAD_F(0x063ec1f2) /* 0.390321681 */, 18 }, + /* 5722 */ { MAD_F(0x063f2156) /* 0.390412651 */, 18 }, + /* 5723 */ { MAD_F(0x063f80bb) /* 0.390503628 */, 18 }, + /* 5724 */ { MAD_F(0x063fe022) /* 0.390594609 */, 18 }, + /* 5725 */ { MAD_F(0x06403f8a) /* 0.390685596 */, 18 }, + /* 5726 */ { MAD_F(0x06409ef3) /* 0.390776588 */, 18 }, + /* 5727 */ { MAD_F(0x0640fe5e) /* 0.390867585 */, 18 }, + + /* 5728 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 18 }, + /* 5729 */ { MAD_F(0x0641bd38) /* 0.391049596 */, 18 }, + /* 5730 */ { MAD_F(0x06421ca7) /* 0.391140609 */, 18 }, + /* 5731 */ { MAD_F(0x06427c18) /* 0.391231627 */, 18 }, + /* 5732 */ { MAD_F(0x0642db8a) /* 0.391322651 */, 18 }, + /* 5733 */ { MAD_F(0x06433afd) /* 0.391413680 */, 18 }, + /* 5734 */ { MAD_F(0x06439a72) /* 0.391504714 */, 18 }, + /* 5735 */ { MAD_F(0x0643f9e9) /* 0.391595754 */, 18 }, + /* 5736 */ { MAD_F(0x06445960) /* 0.391686799 */, 18 }, + /* 5737 */ { MAD_F(0x0644b8d9) /* 0.391777849 */, 18 }, + /* 5738 */ { MAD_F(0x06451854) /* 0.391868905 */, 18 }, + /* 5739 */ { MAD_F(0x064577d0) /* 0.391959966 */, 18 }, + /* 5740 */ { MAD_F(0x0645d74d) /* 0.392051032 */, 18 }, + /* 5741 */ { MAD_F(0x064636cc) /* 0.392142103 */, 18 }, + /* 5742 */ { MAD_F(0x0646964c) /* 0.392233180 */, 18 }, + /* 5743 */ { MAD_F(0x0646f5ce) /* 0.392324262 */, 18 }, + + /* 5744 */ { MAD_F(0x06475551) /* 0.392415349 */, 18 }, + /* 5745 */ { MAD_F(0x0647b4d5) /* 0.392506442 */, 18 }, + /* 5746 */ { MAD_F(0x0648145b) /* 0.392597540 */, 18 }, + /* 5747 */ { MAD_F(0x064873e3) /* 0.392688643 */, 18 }, + /* 5748 */ { MAD_F(0x0648d36b) /* 0.392779751 */, 18 }, + /* 5749 */ { MAD_F(0x064932f6) /* 0.392870865 */, 18 }, + /* 5750 */ { MAD_F(0x06499281) /* 0.392961984 */, 18 }, + /* 5751 */ { MAD_F(0x0649f20e) /* 0.393053108 */, 18 }, + /* 5752 */ { MAD_F(0x064a519c) /* 0.393144238 */, 18 }, + /* 5753 */ { MAD_F(0x064ab12c) /* 0.393235372 */, 18 }, + /* 5754 */ { MAD_F(0x064b10be) /* 0.393326513 */, 18 }, + /* 5755 */ { MAD_F(0x064b7050) /* 0.393417658 */, 18 }, + /* 5756 */ { MAD_F(0x064bcfe4) /* 0.393508809 */, 18 }, + /* 5757 */ { MAD_F(0x064c2f7a) /* 0.393599965 */, 18 }, + /* 5758 */ { MAD_F(0x064c8f11) /* 0.393691126 */, 18 }, + /* 5759 */ { MAD_F(0x064ceea9) /* 0.393782292 */, 18 }, + + /* 5760 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 18 }, + /* 5761 */ { MAD_F(0x064dadde) /* 0.393964641 */, 18 }, + /* 5762 */ { MAD_F(0x064e0d7a) /* 0.394055823 */, 18 }, + /* 5763 */ { MAD_F(0x064e6d18) /* 0.394147011 */, 18 }, + /* 5764 */ { MAD_F(0x064eccb8) /* 0.394238204 */, 18 }, + /* 5765 */ { MAD_F(0x064f2c59) /* 0.394329402 */, 18 }, + /* 5766 */ { MAD_F(0x064f8bfb) /* 0.394420605 */, 18 }, + /* 5767 */ { MAD_F(0x064feb9e) /* 0.394511814 */, 18 }, + /* 5768 */ { MAD_F(0x06504b44) /* 0.394603028 */, 18 }, + /* 5769 */ { MAD_F(0x0650aaea) /* 0.394694247 */, 18 }, + /* 5770 */ { MAD_F(0x06510a92) /* 0.394785472 */, 18 }, + /* 5771 */ { MAD_F(0x06516a3b) /* 0.394876702 */, 18 }, + /* 5772 */ { MAD_F(0x0651c9e6) /* 0.394967937 */, 18 }, + /* 5773 */ { MAD_F(0x06522992) /* 0.395059177 */, 18 }, + /* 5774 */ { MAD_F(0x06528940) /* 0.395150423 */, 18 }, + /* 5775 */ { MAD_F(0x0652e8ef) /* 0.395241673 */, 18 }, + + /* 5776 */ { MAD_F(0x0653489f) /* 0.395332930 */, 18 }, + /* 5777 */ { MAD_F(0x0653a851) /* 0.395424191 */, 18 }, + /* 5778 */ { MAD_F(0x06540804) /* 0.395515458 */, 18 }, + /* 5779 */ { MAD_F(0x065467b9) /* 0.395606730 */, 18 }, + /* 5780 */ { MAD_F(0x0654c76f) /* 0.395698007 */, 18 }, + /* 5781 */ { MAD_F(0x06552726) /* 0.395789289 */, 18 }, + /* 5782 */ { MAD_F(0x065586df) /* 0.395880577 */, 18 }, + /* 5783 */ { MAD_F(0x0655e699) /* 0.395971870 */, 18 }, + /* 5784 */ { MAD_F(0x06564655) /* 0.396063168 */, 18 }, + /* 5785 */ { MAD_F(0x0656a612) /* 0.396154472 */, 18 }, + /* 5786 */ { MAD_F(0x065705d0) /* 0.396245780 */, 18 }, + /* 5787 */ { MAD_F(0x06576590) /* 0.396337094 */, 18 }, + /* 5788 */ { MAD_F(0x0657c552) /* 0.396428414 */, 18 }, + /* 5789 */ { MAD_F(0x06582514) /* 0.396519738 */, 18 }, + /* 5790 */ { MAD_F(0x065884d9) /* 0.396611068 */, 18 }, + /* 5791 */ { MAD_F(0x0658e49e) /* 0.396702403 */, 18 }, + + /* 5792 */ { MAD_F(0x06594465) /* 0.396793743 */, 18 }, + /* 5793 */ { MAD_F(0x0659a42e) /* 0.396885089 */, 18 }, + /* 5794 */ { MAD_F(0x065a03f7) /* 0.396976440 */, 18 }, + /* 5795 */ { MAD_F(0x065a63c3) /* 0.397067796 */, 18 }, + /* 5796 */ { MAD_F(0x065ac38f) /* 0.397159157 */, 18 }, + /* 5797 */ { MAD_F(0x065b235d) /* 0.397250524 */, 18 }, + /* 5798 */ { MAD_F(0x065b832d) /* 0.397341896 */, 18 }, + /* 5799 */ { MAD_F(0x065be2fe) /* 0.397433273 */, 18 }, + /* 5800 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 18 }, + /* 5801 */ { MAD_F(0x065ca2a3) /* 0.397616043 */, 18 }, + /* 5802 */ { MAD_F(0x065d0279) /* 0.397707436 */, 18 }, + /* 5803 */ { MAD_F(0x065d624f) /* 0.397798834 */, 18 }, + /* 5804 */ { MAD_F(0x065dc227) /* 0.397890237 */, 18 }, + /* 5805 */ { MAD_F(0x065e2200) /* 0.397981646 */, 18 }, + /* 5806 */ { MAD_F(0x065e81db) /* 0.398073059 */, 18 }, + /* 5807 */ { MAD_F(0x065ee1b7) /* 0.398164479 */, 18 }, + + /* 5808 */ { MAD_F(0x065f4195) /* 0.398255903 */, 18 }, + /* 5809 */ { MAD_F(0x065fa174) /* 0.398347333 */, 18 }, + /* 5810 */ { MAD_F(0x06600154) /* 0.398438767 */, 18 }, + /* 5811 */ { MAD_F(0x06606136) /* 0.398530207 */, 18 }, + /* 5812 */ { MAD_F(0x0660c119) /* 0.398621653 */, 18 }, + /* 5813 */ { MAD_F(0x066120fd) /* 0.398713103 */, 18 }, + /* 5814 */ { MAD_F(0x066180e3) /* 0.398804559 */, 18 }, + /* 5815 */ { MAD_F(0x0661e0cb) /* 0.398896020 */, 18 }, + /* 5816 */ { MAD_F(0x066240b4) /* 0.398987487 */, 18 }, + /* 5817 */ { MAD_F(0x0662a09e) /* 0.399078958 */, 18 }, + /* 5818 */ { MAD_F(0x06630089) /* 0.399170435 */, 18 }, + /* 5819 */ { MAD_F(0x06636077) /* 0.399261917 */, 18 }, + /* 5820 */ { MAD_F(0x0663c065) /* 0.399353404 */, 18 }, + /* 5821 */ { MAD_F(0x06642055) /* 0.399444897 */, 18 }, + /* 5822 */ { MAD_F(0x06648046) /* 0.399536395 */, 18 }, + /* 5823 */ { MAD_F(0x0664e039) /* 0.399627898 */, 18 }, + + /* 5824 */ { MAD_F(0x0665402d) /* 0.399719406 */, 18 }, + /* 5825 */ { MAD_F(0x0665a022) /* 0.399810919 */, 18 }, + /* 5826 */ { MAD_F(0x06660019) /* 0.399902438 */, 18 }, + /* 5827 */ { MAD_F(0x06666011) /* 0.399993962 */, 18 }, + /* 5828 */ { MAD_F(0x0666c00b) /* 0.400085491 */, 18 }, + /* 5829 */ { MAD_F(0x06672006) /* 0.400177026 */, 18 }, + /* 5830 */ { MAD_F(0x06678003) /* 0.400268565 */, 18 }, + /* 5831 */ { MAD_F(0x0667e000) /* 0.400360110 */, 18 }, + /* 5832 */ { MAD_F(0x06684000) /* 0.400451660 */, 18 }, + /* 5833 */ { MAD_F(0x0668a000) /* 0.400543216 */, 18 }, + /* 5834 */ { MAD_F(0x06690003) /* 0.400634776 */, 18 }, + /* 5835 */ { MAD_F(0x06696006) /* 0.400726342 */, 18 }, + /* 5836 */ { MAD_F(0x0669c00b) /* 0.400817913 */, 18 }, + /* 5837 */ { MAD_F(0x066a2011) /* 0.400909489 */, 18 }, + /* 5838 */ { MAD_F(0x066a8019) /* 0.401001071 */, 18 }, + /* 5839 */ { MAD_F(0x066ae022) /* 0.401092657 */, 18 }, + + /* 5840 */ { MAD_F(0x066b402d) /* 0.401184249 */, 18 }, + /* 5841 */ { MAD_F(0x066ba039) /* 0.401275847 */, 18 }, + /* 5842 */ { MAD_F(0x066c0046) /* 0.401367449 */, 18 }, + /* 5843 */ { MAD_F(0x066c6055) /* 0.401459057 */, 18 }, + /* 5844 */ { MAD_F(0x066cc065) /* 0.401550670 */, 18 }, + /* 5845 */ { MAD_F(0x066d2076) /* 0.401642288 */, 18 }, + /* 5846 */ { MAD_F(0x066d8089) /* 0.401733911 */, 18 }, + /* 5847 */ { MAD_F(0x066de09e) /* 0.401825540 */, 18 }, + /* 5848 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 18 }, + /* 5849 */ { MAD_F(0x066ea0cb) /* 0.402008812 */, 18 }, + /* 5850 */ { MAD_F(0x066f00e3) /* 0.402100457 */, 18 }, + /* 5851 */ { MAD_F(0x066f60fd) /* 0.402192106 */, 18 }, + /* 5852 */ { MAD_F(0x066fc118) /* 0.402283761 */, 18 }, + /* 5853 */ { MAD_F(0x06702135) /* 0.402375420 */, 18 }, + /* 5854 */ { MAD_F(0x06708153) /* 0.402467086 */, 18 }, + /* 5855 */ { MAD_F(0x0670e173) /* 0.402558756 */, 18 }, + + /* 5856 */ { MAD_F(0x06714194) /* 0.402650431 */, 18 }, + /* 5857 */ { MAD_F(0x0671a1b6) /* 0.402742112 */, 18 }, + /* 5858 */ { MAD_F(0x067201da) /* 0.402833798 */, 18 }, + /* 5859 */ { MAD_F(0x067261ff) /* 0.402925489 */, 18 }, + /* 5860 */ { MAD_F(0x0672c226) /* 0.403017186 */, 18 }, + /* 5861 */ { MAD_F(0x0673224e) /* 0.403108887 */, 18 }, + /* 5862 */ { MAD_F(0x06738277) /* 0.403200594 */, 18 }, + /* 5863 */ { MAD_F(0x0673e2a2) /* 0.403292306 */, 18 }, + /* 5864 */ { MAD_F(0x067442ce) /* 0.403384024 */, 18 }, + /* 5865 */ { MAD_F(0x0674a2fc) /* 0.403475746 */, 18 }, + /* 5866 */ { MAD_F(0x0675032b) /* 0.403567474 */, 18 }, + /* 5867 */ { MAD_F(0x0675635b) /* 0.403659207 */, 18 }, + /* 5868 */ { MAD_F(0x0675c38d) /* 0.403750945 */, 18 }, + /* 5869 */ { MAD_F(0x067623c0) /* 0.403842688 */, 18 }, + /* 5870 */ { MAD_F(0x067683f4) /* 0.403934437 */, 18 }, + /* 5871 */ { MAD_F(0x0676e42a) /* 0.404026190 */, 18 }, + + /* 5872 */ { MAD_F(0x06774462) /* 0.404117949 */, 18 }, + /* 5873 */ { MAD_F(0x0677a49b) /* 0.404209714 */, 18 }, + /* 5874 */ { MAD_F(0x067804d5) /* 0.404301483 */, 18 }, + /* 5875 */ { MAD_F(0x06786510) /* 0.404393258 */, 18 }, + /* 5876 */ { MAD_F(0x0678c54d) /* 0.404485037 */, 18 }, + /* 5877 */ { MAD_F(0x0679258c) /* 0.404576822 */, 18 }, + /* 5878 */ { MAD_F(0x067985cb) /* 0.404668613 */, 18 }, + /* 5879 */ { MAD_F(0x0679e60c) /* 0.404760408 */, 18 }, + /* 5880 */ { MAD_F(0x067a464f) /* 0.404852209 */, 18 }, + /* 5881 */ { MAD_F(0x067aa693) /* 0.404944014 */, 18 }, + /* 5882 */ { MAD_F(0x067b06d8) /* 0.405035825 */, 18 }, + /* 5883 */ { MAD_F(0x067b671f) /* 0.405127642 */, 18 }, + /* 5884 */ { MAD_F(0x067bc767) /* 0.405219463 */, 18 }, + /* 5885 */ { MAD_F(0x067c27b1) /* 0.405311290 */, 18 }, + /* 5886 */ { MAD_F(0x067c87fc) /* 0.405403122 */, 18 }, + /* 5887 */ { MAD_F(0x067ce848) /* 0.405494959 */, 18 }, + + /* 5888 */ { MAD_F(0x067d4896) /* 0.405586801 */, 18 }, + /* 5889 */ { MAD_F(0x067da8e5) /* 0.405678648 */, 18 }, + /* 5890 */ { MAD_F(0x067e0935) /* 0.405770501 */, 18 }, + /* 5891 */ { MAD_F(0x067e6987) /* 0.405862359 */, 18 }, + /* 5892 */ { MAD_F(0x067ec9da) /* 0.405954222 */, 18 }, + /* 5893 */ { MAD_F(0x067f2a2f) /* 0.406046090 */, 18 }, + /* 5894 */ { MAD_F(0x067f8a85) /* 0.406137963 */, 18 }, + /* 5895 */ { MAD_F(0x067feadd) /* 0.406229842 */, 18 }, + /* 5896 */ { MAD_F(0x06804b36) /* 0.406321726 */, 18 }, + /* 5897 */ { MAD_F(0x0680ab90) /* 0.406413615 */, 18 }, + /* 5898 */ { MAD_F(0x06810beb) /* 0.406505509 */, 18 }, + /* 5899 */ { MAD_F(0x06816c49) /* 0.406597408 */, 18 }, + /* 5900 */ { MAD_F(0x0681cca7) /* 0.406689313 */, 18 }, + /* 5901 */ { MAD_F(0x06822d07) /* 0.406781223 */, 18 }, + /* 5902 */ { MAD_F(0x06828d68) /* 0.406873138 */, 18 }, + /* 5903 */ { MAD_F(0x0682edcb) /* 0.406965058 */, 18 }, + + /* 5904 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 18 }, + /* 5905 */ { MAD_F(0x0683ae94) /* 0.407148914 */, 18 }, + /* 5906 */ { MAD_F(0x06840efb) /* 0.407240850 */, 18 }, + /* 5907 */ { MAD_F(0x06846f63) /* 0.407332791 */, 18 }, + /* 5908 */ { MAD_F(0x0684cfcd) /* 0.407424737 */, 18 }, + /* 5909 */ { MAD_F(0x06853038) /* 0.407516688 */, 18 }, + /* 5910 */ { MAD_F(0x068590a4) /* 0.407608645 */, 18 }, + /* 5911 */ { MAD_F(0x0685f112) /* 0.407700606 */, 18 }, + /* 5912 */ { MAD_F(0x06865181) /* 0.407792573 */, 18 }, + /* 5913 */ { MAD_F(0x0686b1f2) /* 0.407884545 */, 18 }, + /* 5914 */ { MAD_F(0x06871264) /* 0.407976522 */, 18 }, + /* 5915 */ { MAD_F(0x068772d7) /* 0.408068505 */, 18 }, + /* 5916 */ { MAD_F(0x0687d34c) /* 0.408160492 */, 18 }, + /* 5917 */ { MAD_F(0x068833c2) /* 0.408252485 */, 18 }, + /* 5918 */ { MAD_F(0x06889439) /* 0.408344483 */, 18 }, + /* 5919 */ { MAD_F(0x0688f4b2) /* 0.408436486 */, 18 }, + + /* 5920 */ { MAD_F(0x0689552c) /* 0.408528495 */, 18 }, + /* 5921 */ { MAD_F(0x0689b5a8) /* 0.408620508 */, 18 }, + /* 5922 */ { MAD_F(0x068a1625) /* 0.408712527 */, 18 }, + /* 5923 */ { MAD_F(0x068a76a4) /* 0.408804551 */, 18 }, + /* 5924 */ { MAD_F(0x068ad724) /* 0.408896580 */, 18 }, + /* 5925 */ { MAD_F(0x068b37a5) /* 0.408988614 */, 18 }, + /* 5926 */ { MAD_F(0x068b9827) /* 0.409080653 */, 18 }, + /* 5927 */ { MAD_F(0x068bf8ac) /* 0.409172698 */, 18 }, + /* 5928 */ { MAD_F(0x068c5931) /* 0.409264748 */, 18 }, + /* 5929 */ { MAD_F(0x068cb9b8) /* 0.409356803 */, 18 }, + /* 5930 */ { MAD_F(0x068d1a40) /* 0.409448863 */, 18 }, + /* 5931 */ { MAD_F(0x068d7aca) /* 0.409540928 */, 18 }, + /* 5932 */ { MAD_F(0x068ddb54) /* 0.409632999 */, 18 }, + /* 5933 */ { MAD_F(0x068e3be1) /* 0.409725074 */, 18 }, + /* 5934 */ { MAD_F(0x068e9c6f) /* 0.409817155 */, 18 }, + /* 5935 */ { MAD_F(0x068efcfe) /* 0.409909241 */, 18 }, + + /* 5936 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 18 }, + /* 5937 */ { MAD_F(0x068fbe20) /* 0.410093428 */, 18 }, + /* 5938 */ { MAD_F(0x06901eb4) /* 0.410185530 */, 18 }, + /* 5939 */ { MAD_F(0x06907f48) /* 0.410277637 */, 18 }, + /* 5940 */ { MAD_F(0x0690dfde) /* 0.410369748 */, 18 }, + /* 5941 */ { MAD_F(0x06914076) /* 0.410461865 */, 18 }, + /* 5942 */ { MAD_F(0x0691a10f) /* 0.410553988 */, 18 }, + /* 5943 */ { MAD_F(0x069201a9) /* 0.410646115 */, 18 }, + /* 5944 */ { MAD_F(0x06926245) /* 0.410738247 */, 18 }, + /* 5945 */ { MAD_F(0x0692c2e2) /* 0.410830385 */, 18 }, + /* 5946 */ { MAD_F(0x06932380) /* 0.410922528 */, 18 }, + /* 5947 */ { MAD_F(0x06938420) /* 0.411014676 */, 18 }, + /* 5948 */ { MAD_F(0x0693e4c1) /* 0.411106829 */, 18 }, + /* 5949 */ { MAD_F(0x06944563) /* 0.411198987 */, 18 }, + /* 5950 */ { MAD_F(0x0694a607) /* 0.411291151 */, 18 }, + /* 5951 */ { MAD_F(0x069506ad) /* 0.411383320 */, 18 }, + + /* 5952 */ { MAD_F(0x06956753) /* 0.411475493 */, 18 }, + /* 5953 */ { MAD_F(0x0695c7fc) /* 0.411567672 */, 18 }, + /* 5954 */ { MAD_F(0x069628a5) /* 0.411659857 */, 18 }, + /* 5955 */ { MAD_F(0x06968950) /* 0.411752046 */, 18 }, + /* 5956 */ { MAD_F(0x0696e9fc) /* 0.411844240 */, 18 }, + /* 5957 */ { MAD_F(0x06974aaa) /* 0.411936440 */, 18 }, + /* 5958 */ { MAD_F(0x0697ab59) /* 0.412028645 */, 18 }, + /* 5959 */ { MAD_F(0x06980c09) /* 0.412120855 */, 18 }, + /* 5960 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 18 }, + /* 5961 */ { MAD_F(0x0698cd6e) /* 0.412305290 */, 18 }, + /* 5962 */ { MAD_F(0x06992e23) /* 0.412397516 */, 18 }, + /* 5963 */ { MAD_F(0x06998ed9) /* 0.412489746 */, 18 }, + /* 5964 */ { MAD_F(0x0699ef90) /* 0.412581982 */, 18 }, + /* 5965 */ { MAD_F(0x069a5049) /* 0.412674223 */, 18 }, + /* 5966 */ { MAD_F(0x069ab103) /* 0.412766469 */, 18 }, + /* 5967 */ { MAD_F(0x069b11bf) /* 0.412858720 */, 18 }, + + /* 5968 */ { MAD_F(0x069b727b) /* 0.412950976 */, 18 }, + /* 5969 */ { MAD_F(0x069bd33a) /* 0.413043238 */, 18 }, + /* 5970 */ { MAD_F(0x069c33f9) /* 0.413135505 */, 18 }, + /* 5971 */ { MAD_F(0x069c94ba) /* 0.413227776 */, 18 }, + /* 5972 */ { MAD_F(0x069cf57d) /* 0.413320053 */, 18 }, + /* 5973 */ { MAD_F(0x069d5641) /* 0.413412335 */, 18 }, + /* 5974 */ { MAD_F(0x069db706) /* 0.413504623 */, 18 }, + /* 5975 */ { MAD_F(0x069e17cc) /* 0.413596915 */, 18 }, + /* 5976 */ { MAD_F(0x069e7894) /* 0.413689213 */, 18 }, + /* 5977 */ { MAD_F(0x069ed95e) /* 0.413781515 */, 18 }, + /* 5978 */ { MAD_F(0x069f3a28) /* 0.413873823 */, 18 }, + /* 5979 */ { MAD_F(0x069f9af4) /* 0.413966136 */, 18 }, + /* 5980 */ { MAD_F(0x069ffbc2) /* 0.414058454 */, 18 }, + /* 5981 */ { MAD_F(0x06a05c91) /* 0.414150778 */, 18 }, + /* 5982 */ { MAD_F(0x06a0bd61) /* 0.414243106 */, 18 }, + /* 5983 */ { MAD_F(0x06a11e32) /* 0.414335440 */, 18 }, + + /* 5984 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 18 }, + /* 5985 */ { MAD_F(0x06a1dfda) /* 0.414520122 */, 18 }, + /* 5986 */ { MAD_F(0x06a240b0) /* 0.414612471 */, 18 }, + /* 5987 */ { MAD_F(0x06a2a187) /* 0.414704826 */, 18 }, + /* 5988 */ { MAD_F(0x06a3025f) /* 0.414797185 */, 18 }, + /* 5989 */ { MAD_F(0x06a36339) /* 0.414889549 */, 18 }, + /* 5990 */ { MAD_F(0x06a3c414) /* 0.414981919 */, 18 }, + /* 5991 */ { MAD_F(0x06a424f1) /* 0.415074294 */, 18 }, + /* 5992 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 18 }, + /* 5993 */ { MAD_F(0x06a4e6ae) /* 0.415259059 */, 18 }, + /* 5994 */ { MAD_F(0x06a5478f) /* 0.415351449 */, 18 }, + /* 5995 */ { MAD_F(0x06a5a871) /* 0.415443844 */, 18 }, + /* 5996 */ { MAD_F(0x06a60955) /* 0.415536244 */, 18 }, + /* 5997 */ { MAD_F(0x06a66a3a) /* 0.415628650 */, 18 }, + /* 5998 */ { MAD_F(0x06a6cb20) /* 0.415721061 */, 18 }, + /* 5999 */ { MAD_F(0x06a72c08) /* 0.415813476 */, 18 }, + + /* 6000 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 18 }, + /* 6001 */ { MAD_F(0x06a7eddb) /* 0.415998324 */, 18 }, + /* 6002 */ { MAD_F(0x06a84ec7) /* 0.416090755 */, 18 }, + /* 6003 */ { MAD_F(0x06a8afb4) /* 0.416183191 */, 18 }, + /* 6004 */ { MAD_F(0x06a910a3) /* 0.416275633 */, 18 }, + /* 6005 */ { MAD_F(0x06a97193) /* 0.416368079 */, 18 }, + /* 6006 */ { MAD_F(0x06a9d284) /* 0.416460531 */, 18 }, + /* 6007 */ { MAD_F(0x06aa3377) /* 0.416552988 */, 18 }, + /* 6008 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 18 }, + /* 6009 */ { MAD_F(0x06aaf561) /* 0.416737917 */, 18 }, + /* 6010 */ { MAD_F(0x06ab5657) /* 0.416830389 */, 18 }, + /* 6011 */ { MAD_F(0x06abb750) /* 0.416922867 */, 18 }, + /* 6012 */ { MAD_F(0x06ac1849) /* 0.417015349 */, 18 }, + /* 6013 */ { MAD_F(0x06ac7944) /* 0.417107837 */, 18 }, + /* 6014 */ { MAD_F(0x06acda41) /* 0.417200330 */, 18 }, + /* 6015 */ { MAD_F(0x06ad3b3e) /* 0.417292828 */, 18 }, + + /* 6016 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 18 }, + /* 6017 */ { MAD_F(0x06adfd3e) /* 0.417477839 */, 18 }, + /* 6018 */ { MAD_F(0x06ae5e40) /* 0.417570352 */, 18 }, + /* 6019 */ { MAD_F(0x06aebf43) /* 0.417662871 */, 18 }, + /* 6020 */ { MAD_F(0x06af2047) /* 0.417755394 */, 18 }, + /* 6021 */ { MAD_F(0x06af814d) /* 0.417847923 */, 18 }, + /* 6022 */ { MAD_F(0x06afe255) /* 0.417940457 */, 18 }, + /* 6023 */ { MAD_F(0x06b0435e) /* 0.418032996 */, 18 }, + /* 6024 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 18 }, + /* 6025 */ { MAD_F(0x06b10573) /* 0.418218089 */, 18 }, + /* 6026 */ { MAD_F(0x06b16680) /* 0.418310643 */, 18 }, + /* 6027 */ { MAD_F(0x06b1c78e) /* 0.418403203 */, 18 }, + /* 6028 */ { MAD_F(0x06b2289e) /* 0.418495767 */, 18 }, + /* 6029 */ { MAD_F(0x06b289af) /* 0.418588337 */, 18 }, + /* 6030 */ { MAD_F(0x06b2eac1) /* 0.418680911 */, 18 }, + /* 6031 */ { MAD_F(0x06b34bd5) /* 0.418773491 */, 18 }, + + /* 6032 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 18 }, + /* 6033 */ { MAD_F(0x06b40e00) /* 0.418958666 */, 18 }, + /* 6034 */ { MAD_F(0x06b46f18) /* 0.419051262 */, 18 }, + /* 6035 */ { MAD_F(0x06b4d031) /* 0.419143862 */, 18 }, + /* 6036 */ { MAD_F(0x06b5314c) /* 0.419236467 */, 18 }, + /* 6037 */ { MAD_F(0x06b59268) /* 0.419329078 */, 18 }, + /* 6038 */ { MAD_F(0x06b5f385) /* 0.419421694 */, 18 }, + /* 6039 */ { MAD_F(0x06b654a4) /* 0.419514314 */, 18 }, + /* 6040 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 18 }, + /* 6041 */ { MAD_F(0x06b716e6) /* 0.419699571 */, 18 }, + /* 6042 */ { MAD_F(0x06b77808) /* 0.419792208 */, 18 }, + /* 6043 */ { MAD_F(0x06b7d92d) /* 0.419884849 */, 18 }, + /* 6044 */ { MAD_F(0x06b83a52) /* 0.419977495 */, 18 }, + /* 6045 */ { MAD_F(0x06b89b79) /* 0.420070147 */, 18 }, + /* 6046 */ { MAD_F(0x06b8fca1) /* 0.420162803 */, 18 }, + /* 6047 */ { MAD_F(0x06b95dcb) /* 0.420255465 */, 18 }, + + /* 6048 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 18 }, + /* 6049 */ { MAD_F(0x06ba2023) /* 0.420440803 */, 18 }, + /* 6050 */ { MAD_F(0x06ba8150) /* 0.420533481 */, 18 }, + /* 6051 */ { MAD_F(0x06bae280) /* 0.420626163 */, 18 }, + /* 6052 */ { MAD_F(0x06bb43b0) /* 0.420718850 */, 18 }, + /* 6053 */ { MAD_F(0x06bba4e2) /* 0.420811542 */, 18 }, + /* 6054 */ { MAD_F(0x06bc0615) /* 0.420904240 */, 18 }, + /* 6055 */ { MAD_F(0x06bc674a) /* 0.420996942 */, 18 }, + /* 6056 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 18 }, + /* 6057 */ { MAD_F(0x06bd29b7) /* 0.421182362 */, 18 }, + /* 6058 */ { MAD_F(0x06bd8af0) /* 0.421275080 */, 18 }, + /* 6059 */ { MAD_F(0x06bdec2a) /* 0.421367803 */, 18 }, + /* 6060 */ { MAD_F(0x06be4d66) /* 0.421460531 */, 18 }, + /* 6061 */ { MAD_F(0x06beaea3) /* 0.421553264 */, 18 }, + /* 6062 */ { MAD_F(0x06bf0fe1) /* 0.421646003 */, 18 }, + /* 6063 */ { MAD_F(0x06bf7120) /* 0.421738746 */, 18 }, + + /* 6064 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 18 }, + /* 6065 */ { MAD_F(0x06c033a4) /* 0.421924248 */, 18 }, + /* 6066 */ { MAD_F(0x06c094e7) /* 0.422017007 */, 18 }, + /* 6067 */ { MAD_F(0x06c0f62c) /* 0.422109770 */, 18 }, + /* 6068 */ { MAD_F(0x06c15773) /* 0.422202539 */, 18 }, + /* 6069 */ { MAD_F(0x06c1b8bb) /* 0.422295313 */, 18 }, + /* 6070 */ { MAD_F(0x06c21a04) /* 0.422388092 */, 18 }, + /* 6071 */ { MAD_F(0x06c27b4e) /* 0.422480876 */, 18 }, + /* 6072 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 18 }, + /* 6073 */ { MAD_F(0x06c33de8) /* 0.422666460 */, 18 }, + /* 6074 */ { MAD_F(0x06c39f36) /* 0.422759259 */, 18 }, + /* 6075 */ { MAD_F(0x06c40086) /* 0.422852064 */, 18 }, + /* 6076 */ { MAD_F(0x06c461d8) /* 0.422944873 */, 18 }, + /* 6077 */ { MAD_F(0x06c4c32a) /* 0.423037688 */, 18 }, + /* 6078 */ { MAD_F(0x06c5247f) /* 0.423130508 */, 18 }, + /* 6079 */ { MAD_F(0x06c585d4) /* 0.423223333 */, 18 }, + + /* 6080 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 18 }, + /* 6081 */ { MAD_F(0x06c64883) /* 0.423408997 */, 18 }, + /* 6082 */ { MAD_F(0x06c6a9dd) /* 0.423501838 */, 18 }, + /* 6083 */ { MAD_F(0x06c70b38) /* 0.423594683 */, 18 }, + /* 6084 */ { MAD_F(0x06c76c94) /* 0.423687533 */, 18 }, + /* 6085 */ { MAD_F(0x06c7cdf2) /* 0.423780389 */, 18 }, + /* 6086 */ { MAD_F(0x06c82f51) /* 0.423873249 */, 18 }, + /* 6087 */ { MAD_F(0x06c890b1) /* 0.423966115 */, 18 }, + /* 6088 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 18 }, + /* 6089 */ { MAD_F(0x06c95376) /* 0.424151861 */, 18 }, + /* 6090 */ { MAD_F(0x06c9b4da) /* 0.424244742 */, 18 }, + /* 6091 */ { MAD_F(0x06ca1640) /* 0.424337628 */, 18 }, + /* 6092 */ { MAD_F(0x06ca77a8) /* 0.424430519 */, 18 }, + /* 6093 */ { MAD_F(0x06cad910) /* 0.424523415 */, 18 }, + /* 6094 */ { MAD_F(0x06cb3a7a) /* 0.424616316 */, 18 }, + /* 6095 */ { MAD_F(0x06cb9be5) /* 0.424709222 */, 18 }, + + /* 6096 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 18 }, + /* 6097 */ { MAD_F(0x06cc5ec0) /* 0.424895050 */, 18 }, + /* 6098 */ { MAD_F(0x06ccc030) /* 0.424987971 */, 18 }, + /* 6099 */ { MAD_F(0x06cd21a0) /* 0.425080898 */, 18 }, + /* 6100 */ { MAD_F(0x06cd8313) /* 0.425173829 */, 18 }, + /* 6101 */ { MAD_F(0x06cde486) /* 0.425266766 */, 18 }, + /* 6102 */ { MAD_F(0x06ce45fb) /* 0.425359708 */, 18 }, + /* 6103 */ { MAD_F(0x06cea771) /* 0.425452655 */, 18 }, + /* 6104 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 18 }, + /* 6105 */ { MAD_F(0x06cf6a62) /* 0.425638564 */, 18 }, + /* 6106 */ { MAD_F(0x06cfcbdc) /* 0.425731526 */, 18 }, + /* 6107 */ { MAD_F(0x06d02d58) /* 0.425824493 */, 18 }, + /* 6108 */ { MAD_F(0x06d08ed5) /* 0.425917465 */, 18 }, + /* 6109 */ { MAD_F(0x06d0f053) /* 0.426010443 */, 18 }, + /* 6110 */ { MAD_F(0x06d151d3) /* 0.426103425 */, 18 }, + /* 6111 */ { MAD_F(0x06d1b354) /* 0.426196412 */, 18 }, + + /* 6112 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 18 }, + /* 6113 */ { MAD_F(0x06d2765a) /* 0.426382403 */, 18 }, + /* 6114 */ { MAD_F(0x06d2d7e0) /* 0.426475405 */, 18 }, + /* 6115 */ { MAD_F(0x06d33966) /* 0.426568413 */, 18 }, + /* 6116 */ { MAD_F(0x06d39aee) /* 0.426661426 */, 18 }, + /* 6117 */ { MAD_F(0x06d3fc77) /* 0.426754444 */, 18 }, + /* 6118 */ { MAD_F(0x06d45e02) /* 0.426847467 */, 18 }, + /* 6119 */ { MAD_F(0x06d4bf8e) /* 0.426940495 */, 18 }, + /* 6120 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 18 }, + /* 6121 */ { MAD_F(0x06d582aa) /* 0.427126566 */, 18 }, + /* 6122 */ { MAD_F(0x06d5e43a) /* 0.427219609 */, 18 }, + /* 6123 */ { MAD_F(0x06d645cc) /* 0.427312657 */, 18 }, + /* 6124 */ { MAD_F(0x06d6a75f) /* 0.427405711 */, 18 }, + /* 6125 */ { MAD_F(0x06d708f3) /* 0.427498769 */, 18 }, + /* 6126 */ { MAD_F(0x06d76a88) /* 0.427591833 */, 18 }, + /* 6127 */ { MAD_F(0x06d7cc1f) /* 0.427684901 */, 18 }, + + /* 6128 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 18 }, + /* 6129 */ { MAD_F(0x06d88f51) /* 0.427871054 */, 18 }, + /* 6130 */ { MAD_F(0x06d8f0ec) /* 0.427964137 */, 18 }, + /* 6131 */ { MAD_F(0x06d95288) /* 0.428057226 */, 18 }, + /* 6132 */ { MAD_F(0x06d9b426) /* 0.428150320 */, 18 }, + /* 6133 */ { MAD_F(0x06da15c5) /* 0.428243419 */, 18 }, + /* 6134 */ { MAD_F(0x06da7766) /* 0.428336523 */, 18 }, + /* 6135 */ { MAD_F(0x06dad907) /* 0.428429632 */, 18 }, + /* 6136 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 18 }, + /* 6137 */ { MAD_F(0x06db9c4f) /* 0.428615865 */, 18 }, + /* 6138 */ { MAD_F(0x06dbfdf5) /* 0.428708989 */, 18 }, + /* 6139 */ { MAD_F(0x06dc5f9c) /* 0.428802119 */, 18 }, + /* 6140 */ { MAD_F(0x06dcc145) /* 0.428895253 */, 18 }, + /* 6141 */ { MAD_F(0x06dd22ee) /* 0.428988392 */, 18 }, + /* 6142 */ { MAD_F(0x06dd849a) /* 0.429081537 */, 18 }, + /* 6143 */ { MAD_F(0x06dde646) /* 0.429174686 */, 18 }, + + /* 6144 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 18 }, + /* 6145 */ { MAD_F(0x06dea9a4) /* 0.429361001 */, 18 }, + /* 6146 */ { MAD_F(0x06df0b54) /* 0.429454165 */, 18 }, + /* 6147 */ { MAD_F(0x06df6d06) /* 0.429547335 */, 18 }, + /* 6148 */ { MAD_F(0x06dfceba) /* 0.429640510 */, 18 }, + /* 6149 */ { MAD_F(0x06e0306f) /* 0.429733690 */, 18 }, + /* 6150 */ { MAD_F(0x06e09225) /* 0.429826874 */, 18 }, + /* 6151 */ { MAD_F(0x06e0f3dc) /* 0.429920064 */, 18 }, + /* 6152 */ { MAD_F(0x06e15595) /* 0.430013259 */, 18 }, + /* 6153 */ { MAD_F(0x06e1b74f) /* 0.430106459 */, 18 }, + /* 6154 */ { MAD_F(0x06e2190b) /* 0.430199664 */, 18 }, + /* 6155 */ { MAD_F(0x06e27ac8) /* 0.430292875 */, 18 }, + /* 6156 */ { MAD_F(0x06e2dc86) /* 0.430386090 */, 18 }, + /* 6157 */ { MAD_F(0x06e33e46) /* 0.430479310 */, 18 }, + /* 6158 */ { MAD_F(0x06e3a007) /* 0.430572535 */, 18 }, + /* 6159 */ { MAD_F(0x06e401c9) /* 0.430665765 */, 18 }, + + /* 6160 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 18 }, + /* 6161 */ { MAD_F(0x06e4c552) /* 0.430852241 */, 18 }, + /* 6162 */ { MAD_F(0x06e52718) /* 0.430945487 */, 18 }, + /* 6163 */ { MAD_F(0x06e588e0) /* 0.431038737 */, 18 }, + /* 6164 */ { MAD_F(0x06e5eaa9) /* 0.431131993 */, 18 }, + /* 6165 */ { MAD_F(0x06e64c73) /* 0.431225253 */, 18 }, + /* 6166 */ { MAD_F(0x06e6ae3f) /* 0.431318519 */, 18 }, + /* 6167 */ { MAD_F(0x06e7100c) /* 0.431411790 */, 18 }, + /* 6168 */ { MAD_F(0x06e771db) /* 0.431505065 */, 18 }, + /* 6169 */ { MAD_F(0x06e7d3ab) /* 0.431598346 */, 18 }, + /* 6170 */ { MAD_F(0x06e8357c) /* 0.431691632 */, 18 }, + /* 6171 */ { MAD_F(0x06e8974e) /* 0.431784923 */, 18 }, + /* 6172 */ { MAD_F(0x06e8f922) /* 0.431878218 */, 18 }, + /* 6173 */ { MAD_F(0x06e95af8) /* 0.431971519 */, 18 }, + /* 6174 */ { MAD_F(0x06e9bcce) /* 0.432064825 */, 18 }, + /* 6175 */ { MAD_F(0x06ea1ea6) /* 0.432158136 */, 18 }, + + /* 6176 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 18 }, + /* 6177 */ { MAD_F(0x06eae25a) /* 0.432344773 */, 18 }, + /* 6178 */ { MAD_F(0x06eb4436) /* 0.432438099 */, 18 }, + /* 6179 */ { MAD_F(0x06eba614) /* 0.432531431 */, 18 }, + /* 6180 */ { MAD_F(0x06ec07f2) /* 0.432624767 */, 18 }, + /* 6181 */ { MAD_F(0x06ec69d2) /* 0.432718108 */, 18 }, + /* 6182 */ { MAD_F(0x06eccbb4) /* 0.432811454 */, 18 }, + /* 6183 */ { MAD_F(0x06ed2d97) /* 0.432904805 */, 18 }, + /* 6184 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 18 }, + /* 6185 */ { MAD_F(0x06edf160) /* 0.433091523 */, 18 }, + /* 6186 */ { MAD_F(0x06ee5347) /* 0.433184889 */, 18 }, + /* 6187 */ { MAD_F(0x06eeb52f) /* 0.433278261 */, 18 }, + /* 6188 */ { MAD_F(0x06ef1719) /* 0.433371637 */, 18 }, + /* 6189 */ { MAD_F(0x06ef7904) /* 0.433465019 */, 18 }, + /* 6190 */ { MAD_F(0x06efdaf0) /* 0.433558405 */, 18 }, + /* 6191 */ { MAD_F(0x06f03cde) /* 0.433651797 */, 18 }, + + /* 6192 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 18 }, + /* 6193 */ { MAD_F(0x06f100bd) /* 0.433838595 */, 18 }, + /* 6194 */ { MAD_F(0x06f162ae) /* 0.433932001 */, 18 }, + /* 6195 */ { MAD_F(0x06f1c4a1) /* 0.434025413 */, 18 }, + /* 6196 */ { MAD_F(0x06f22696) /* 0.434118830 */, 18 }, + /* 6197 */ { MAD_F(0x06f2888b) /* 0.434212251 */, 18 }, + /* 6198 */ { MAD_F(0x06f2ea82) /* 0.434305678 */, 18 }, + /* 6199 */ { MAD_F(0x06f34c7b) /* 0.434399110 */, 18 }, + /* 6200 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 18 }, + /* 6201 */ { MAD_F(0x06f41070) /* 0.434585988 */, 18 }, + /* 6202 */ { MAD_F(0x06f4726c) /* 0.434679435 */, 18 }, + /* 6203 */ { MAD_F(0x06f4d46a) /* 0.434772887 */, 18 }, + /* 6204 */ { MAD_F(0x06f53669) /* 0.434866344 */, 18 }, + /* 6205 */ { MAD_F(0x06f59869) /* 0.434959806 */, 18 }, + /* 6206 */ { MAD_F(0x06f5fa6b) /* 0.435053272 */, 18 }, + /* 6207 */ { MAD_F(0x06f65c6e) /* 0.435146744 */, 18 }, + + /* 6208 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 18 }, + /* 6209 */ { MAD_F(0x06f72079) /* 0.435333703 */, 18 }, + /* 6210 */ { MAD_F(0x06f78280) /* 0.435427190 */, 18 }, + /* 6211 */ { MAD_F(0x06f7e489) /* 0.435520682 */, 18 }, + /* 6212 */ { MAD_F(0x06f84693) /* 0.435614179 */, 18 }, + /* 6213 */ { MAD_F(0x06f8a89e) /* 0.435707681 */, 18 }, + /* 6214 */ { MAD_F(0x06f90aaa) /* 0.435801188 */, 18 }, + /* 6215 */ { MAD_F(0x06f96cb8) /* 0.435894700 */, 18 }, + /* 6216 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 18 }, + /* 6217 */ { MAD_F(0x06fa30d8) /* 0.436081739 */, 18 }, + /* 6218 */ { MAD_F(0x06fa92ea) /* 0.436175266 */, 18 }, + /* 6219 */ { MAD_F(0x06faf4fe) /* 0.436268799 */, 18 }, + /* 6220 */ { MAD_F(0x06fb5712) /* 0.436362336 */, 18 }, + /* 6221 */ { MAD_F(0x06fbb928) /* 0.436455878 */, 18 }, + /* 6222 */ { MAD_F(0x06fc1b40) /* 0.436549425 */, 18 }, + /* 6223 */ { MAD_F(0x06fc7d58) /* 0.436642977 */, 18 }, + + /* 6224 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 18 }, + /* 6225 */ { MAD_F(0x06fd418e) /* 0.436830096 */, 18 }, + /* 6226 */ { MAD_F(0x06fda3ab) /* 0.436923664 */, 18 }, + /* 6227 */ { MAD_F(0x06fe05c9) /* 0.437017236 */, 18 }, + /* 6228 */ { MAD_F(0x06fe67e8) /* 0.437110813 */, 18 }, + /* 6229 */ { MAD_F(0x06feca09) /* 0.437204395 */, 18 }, + /* 6230 */ { MAD_F(0x06ff2c2b) /* 0.437297982 */, 18 }, + /* 6231 */ { MAD_F(0x06ff8e4f) /* 0.437391575 */, 18 }, + /* 6232 */ { MAD_F(0x06fff073) /* 0.437485172 */, 18 }, + /* 6233 */ { MAD_F(0x0700529a) /* 0.437578774 */, 18 }, + /* 6234 */ { MAD_F(0x0700b4c1) /* 0.437672381 */, 18 }, + /* 6235 */ { MAD_F(0x070116ea) /* 0.437765994 */, 18 }, + /* 6236 */ { MAD_F(0x07017914) /* 0.437859611 */, 18 }, + /* 6237 */ { MAD_F(0x0701db40) /* 0.437953233 */, 18 }, + /* 6238 */ { MAD_F(0x07023d6c) /* 0.438046860 */, 18 }, + /* 6239 */ { MAD_F(0x07029f9b) /* 0.438140493 */, 18 }, + + /* 6240 */ { MAD_F(0x070301ca) /* 0.438234130 */, 18 }, + /* 6241 */ { MAD_F(0x070363fb) /* 0.438327772 */, 18 }, + /* 6242 */ { MAD_F(0x0703c62d) /* 0.438421419 */, 18 }, + /* 6243 */ { MAD_F(0x07042861) /* 0.438515072 */, 18 }, + /* 6244 */ { MAD_F(0x07048a96) /* 0.438608729 */, 18 }, + /* 6245 */ { MAD_F(0x0704eccc) /* 0.438702391 */, 18 }, + /* 6246 */ { MAD_F(0x07054f04) /* 0.438796059 */, 18 }, + /* 6247 */ { MAD_F(0x0705b13d) /* 0.438889731 */, 18 }, + /* 6248 */ { MAD_F(0x07061377) /* 0.438983408 */, 18 }, + /* 6249 */ { MAD_F(0x070675b3) /* 0.439077090 */, 18 }, + /* 6250 */ { MAD_F(0x0706d7f0) /* 0.439170778 */, 18 }, + /* 6251 */ { MAD_F(0x07073a2e) /* 0.439264470 */, 18 }, + /* 6252 */ { MAD_F(0x07079c6e) /* 0.439358167 */, 18 }, + /* 6253 */ { MAD_F(0x0707feaf) /* 0.439451869 */, 18 }, + /* 6254 */ { MAD_F(0x070860f1) /* 0.439545577 */, 18 }, + /* 6255 */ { MAD_F(0x0708c335) /* 0.439639289 */, 18 }, + + /* 6256 */ { MAD_F(0x0709257a) /* 0.439733006 */, 18 }, + /* 6257 */ { MAD_F(0x070987c0) /* 0.439826728 */, 18 }, + /* 6258 */ { MAD_F(0x0709ea08) /* 0.439920456 */, 18 }, + /* 6259 */ { MAD_F(0x070a4c51) /* 0.440014188 */, 18 }, + /* 6260 */ { MAD_F(0x070aae9b) /* 0.440107925 */, 18 }, + /* 6261 */ { MAD_F(0x070b10e7) /* 0.440201667 */, 18 }, + /* 6262 */ { MAD_F(0x070b7334) /* 0.440295414 */, 18 }, + /* 6263 */ { MAD_F(0x070bd583) /* 0.440389167 */, 18 }, + /* 6264 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 18 }, + /* 6265 */ { MAD_F(0x070c9a23) /* 0.440576686 */, 18 }, + /* 6266 */ { MAD_F(0x070cfc76) /* 0.440670453 */, 18 }, + /* 6267 */ { MAD_F(0x070d5eca) /* 0.440764225 */, 18 }, + /* 6268 */ { MAD_F(0x070dc11f) /* 0.440858002 */, 18 }, + /* 6269 */ { MAD_F(0x070e2375) /* 0.440951784 */, 18 }, + /* 6270 */ { MAD_F(0x070e85cd) /* 0.441045572 */, 18 }, + /* 6271 */ { MAD_F(0x070ee826) /* 0.441139364 */, 18 }, + + /* 6272 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 18 }, + /* 6273 */ { MAD_F(0x070facdc) /* 0.441326963 */, 18 }, + /* 6274 */ { MAD_F(0x07100f39) /* 0.441420770 */, 18 }, + /* 6275 */ { MAD_F(0x07107198) /* 0.441514582 */, 18 }, + /* 6276 */ { MAD_F(0x0710d3f8) /* 0.441608399 */, 18 }, + /* 6277 */ { MAD_F(0x07113659) /* 0.441702221 */, 18 }, + /* 6278 */ { MAD_F(0x071198bb) /* 0.441796048 */, 18 }, + /* 6279 */ { MAD_F(0x0711fb1f) /* 0.441889880 */, 18 }, + /* 6280 */ { MAD_F(0x07125d84) /* 0.441983717 */, 18 }, + /* 6281 */ { MAD_F(0x0712bfeb) /* 0.442077559 */, 18 }, + /* 6282 */ { MAD_F(0x07132253) /* 0.442171406 */, 18 }, + /* 6283 */ { MAD_F(0x071384bc) /* 0.442265257 */, 18 }, + /* 6284 */ { MAD_F(0x0713e726) /* 0.442359114 */, 18 }, + /* 6285 */ { MAD_F(0x07144992) /* 0.442452976 */, 18 }, + /* 6286 */ { MAD_F(0x0714abff) /* 0.442546843 */, 18 }, + /* 6287 */ { MAD_F(0x07150e6e) /* 0.442640715 */, 18 }, + + /* 6288 */ { MAD_F(0x071570de) /* 0.442734592 */, 18 }, + /* 6289 */ { MAD_F(0x0715d34f) /* 0.442828473 */, 18 }, + /* 6290 */ { MAD_F(0x071635c1) /* 0.442922360 */, 18 }, + /* 6291 */ { MAD_F(0x07169835) /* 0.443016252 */, 18 }, + /* 6292 */ { MAD_F(0x0716faaa) /* 0.443110148 */, 18 }, + /* 6293 */ { MAD_F(0x07175d21) /* 0.443204050 */, 18 }, + /* 6294 */ { MAD_F(0x0717bf99) /* 0.443297957 */, 18 }, + /* 6295 */ { MAD_F(0x07182212) /* 0.443391868 */, 18 }, + /* 6296 */ { MAD_F(0x0718848d) /* 0.443485785 */, 18 }, + /* 6297 */ { MAD_F(0x0718e709) /* 0.443579706 */, 18 }, + /* 6298 */ { MAD_F(0x07194986) /* 0.443673633 */, 18 }, + /* 6299 */ { MAD_F(0x0719ac04) /* 0.443767564 */, 18 }, + /* 6300 */ { MAD_F(0x071a0e84) /* 0.443861501 */, 18 }, + /* 6301 */ { MAD_F(0x071a7105) /* 0.443955442 */, 18 }, + /* 6302 */ { MAD_F(0x071ad388) /* 0.444049389 */, 18 }, + /* 6303 */ { MAD_F(0x071b360c) /* 0.444143340 */, 18 }, + + /* 6304 */ { MAD_F(0x071b9891) /* 0.444237296 */, 18 }, + /* 6305 */ { MAD_F(0x071bfb18) /* 0.444331258 */, 18 }, + /* 6306 */ { MAD_F(0x071c5d9f) /* 0.444425224 */, 18 }, + /* 6307 */ { MAD_F(0x071cc029) /* 0.444519195 */, 18 }, + /* 6308 */ { MAD_F(0x071d22b3) /* 0.444613171 */, 18 }, + /* 6309 */ { MAD_F(0x071d853f) /* 0.444707153 */, 18 }, + /* 6310 */ { MAD_F(0x071de7cc) /* 0.444801139 */, 18 }, + /* 6311 */ { MAD_F(0x071e4a5b) /* 0.444895130 */, 18 }, + /* 6312 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 18 }, + /* 6313 */ { MAD_F(0x071f0f7c) /* 0.445083127 */, 18 }, + /* 6314 */ { MAD_F(0x071f720e) /* 0.445177133 */, 18 }, + /* 6315 */ { MAD_F(0x071fd4a2) /* 0.445271144 */, 18 }, + /* 6316 */ { MAD_F(0x07203737) /* 0.445365160 */, 18 }, + /* 6317 */ { MAD_F(0x072099ce) /* 0.445459181 */, 18 }, + /* 6318 */ { MAD_F(0x0720fc66) /* 0.445553206 */, 18 }, + /* 6319 */ { MAD_F(0x07215eff) /* 0.445647237 */, 18 }, + + /* 6320 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 18 }, + /* 6321 */ { MAD_F(0x07222436) /* 0.445835314 */, 18 }, + /* 6322 */ { MAD_F(0x072286d3) /* 0.445929359 */, 18 }, + /* 6323 */ { MAD_F(0x0722e971) /* 0.446023410 */, 18 }, + /* 6324 */ { MAD_F(0x07234c11) /* 0.446117466 */, 18 }, + /* 6325 */ { MAD_F(0x0723aeb2) /* 0.446211526 */, 18 }, + /* 6326 */ { MAD_F(0x07241155) /* 0.446305592 */, 18 }, + /* 6327 */ { MAD_F(0x072473f9) /* 0.446399662 */, 18 }, + /* 6328 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 18 }, + /* 6329 */ { MAD_F(0x07253944) /* 0.446587818 */, 18 }, + /* 6330 */ { MAD_F(0x07259bec) /* 0.446681903 */, 18 }, + /* 6331 */ { MAD_F(0x0725fe95) /* 0.446775994 */, 18 }, + /* 6332 */ { MAD_F(0x07266140) /* 0.446870089 */, 18 }, + /* 6333 */ { MAD_F(0x0726c3ec) /* 0.446964189 */, 18 }, + /* 6334 */ { MAD_F(0x07272699) /* 0.447058294 */, 18 }, + /* 6335 */ { MAD_F(0x07278947) /* 0.447152404 */, 18 }, + + /* 6336 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 18 }, + /* 6337 */ { MAD_F(0x07284ea8) /* 0.447340639 */, 18 }, + /* 6338 */ { MAD_F(0x0728b15b) /* 0.447434764 */, 18 }, + /* 6339 */ { MAD_F(0x0729140f) /* 0.447528894 */, 18 }, + /* 6340 */ { MAD_F(0x072976c4) /* 0.447623029 */, 18 }, + /* 6341 */ { MAD_F(0x0729d97a) /* 0.447717169 */, 18 }, + /* 6342 */ { MAD_F(0x072a3c32) /* 0.447811314 */, 18 }, + /* 6343 */ { MAD_F(0x072a9eeb) /* 0.447905463 */, 18 }, + /* 6344 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 18 }, + /* 6345 */ { MAD_F(0x072b6461) /* 0.448093778 */, 18 }, + /* 6346 */ { MAD_F(0x072bc71e) /* 0.448187942 */, 18 }, + /* 6347 */ { MAD_F(0x072c29dd) /* 0.448282112 */, 18 }, + /* 6348 */ { MAD_F(0x072c8c9d) /* 0.448376286 */, 18 }, + /* 6349 */ { MAD_F(0x072cef5e) /* 0.448470466 */, 18 }, + /* 6350 */ { MAD_F(0x072d5220) /* 0.448564650 */, 18 }, + /* 6351 */ { MAD_F(0x072db4e4) /* 0.448658839 */, 18 }, + + /* 6352 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 18 }, + /* 6353 */ { MAD_F(0x072e7a6f) /* 0.448847233 */, 18 }, + /* 6354 */ { MAD_F(0x072edd37) /* 0.448941437 */, 18 }, + /* 6355 */ { MAD_F(0x072f4000) /* 0.449035646 */, 18 }, + /* 6356 */ { MAD_F(0x072fa2ca) /* 0.449129860 */, 18 }, + /* 6357 */ { MAD_F(0x07300596) /* 0.449224079 */, 18 }, + /* 6358 */ { MAD_F(0x07306863) /* 0.449318303 */, 18 }, + /* 6359 */ { MAD_F(0x0730cb32) /* 0.449412531 */, 18 }, + /* 6360 */ { MAD_F(0x07312e01) /* 0.449506765 */, 18 }, + /* 6361 */ { MAD_F(0x073190d2) /* 0.449601004 */, 18 }, + /* 6362 */ { MAD_F(0x0731f3a5) /* 0.449695247 */, 18 }, + /* 6363 */ { MAD_F(0x07325678) /* 0.449789496 */, 18 }, + /* 6364 */ { MAD_F(0x0732b94d) /* 0.449883749 */, 18 }, + /* 6365 */ { MAD_F(0x07331c23) /* 0.449978008 */, 18 }, + /* 6366 */ { MAD_F(0x07337efb) /* 0.450072271 */, 18 }, + /* 6367 */ { MAD_F(0x0733e1d4) /* 0.450166540 */, 18 }, + + /* 6368 */ { MAD_F(0x073444ae) /* 0.450260813 */, 18 }, + /* 6369 */ { MAD_F(0x0734a78a) /* 0.450355091 */, 18 }, + /* 6370 */ { MAD_F(0x07350a67) /* 0.450449374 */, 18 }, + /* 6371 */ { MAD_F(0x07356d45) /* 0.450543662 */, 18 }, + /* 6372 */ { MAD_F(0x0735d025) /* 0.450637955 */, 18 }, + /* 6373 */ { MAD_F(0x07363306) /* 0.450732253 */, 18 }, + /* 6374 */ { MAD_F(0x073695e8) /* 0.450826556 */, 18 }, + /* 6375 */ { MAD_F(0x0736f8cb) /* 0.450920864 */, 18 }, + /* 6376 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 18 }, + /* 6377 */ { MAD_F(0x0737be96) /* 0.451109494 */, 18 }, + /* 6378 */ { MAD_F(0x0738217e) /* 0.451203817 */, 18 }, + /* 6379 */ { MAD_F(0x07388467) /* 0.451298144 */, 18 }, + /* 6380 */ { MAD_F(0x0738e751) /* 0.451392477 */, 18 }, + /* 6381 */ { MAD_F(0x07394a3d) /* 0.451486814 */, 18 }, + /* 6382 */ { MAD_F(0x0739ad29) /* 0.451581156 */, 18 }, + /* 6383 */ { MAD_F(0x073a1017) /* 0.451675503 */, 18 }, + + /* 6384 */ { MAD_F(0x073a7307) /* 0.451769856 */, 18 }, + /* 6385 */ { MAD_F(0x073ad5f8) /* 0.451864213 */, 18 }, + /* 6386 */ { MAD_F(0x073b38ea) /* 0.451958575 */, 18 }, + /* 6387 */ { MAD_F(0x073b9bdd) /* 0.452052942 */, 18 }, + /* 6388 */ { MAD_F(0x073bfed2) /* 0.452147313 */, 18 }, + /* 6389 */ { MAD_F(0x073c61c8) /* 0.452241690 */, 18 }, + /* 6390 */ { MAD_F(0x073cc4bf) /* 0.452336072 */, 18 }, + /* 6391 */ { MAD_F(0x073d27b8) /* 0.452430458 */, 18 }, + /* 6392 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 18 }, + /* 6393 */ { MAD_F(0x073dedae) /* 0.452619246 */, 18 }, + /* 6394 */ { MAD_F(0x073e50aa) /* 0.452713648 */, 18 }, + /* 6395 */ { MAD_F(0x073eb3a8) /* 0.452808054 */, 18 }, + /* 6396 */ { MAD_F(0x073f16a8) /* 0.452902465 */, 18 }, + /* 6397 */ { MAD_F(0x073f79a8) /* 0.452996882 */, 18 }, + /* 6398 */ { MAD_F(0x073fdcaa) /* 0.453091303 */, 18 }, + /* 6399 */ { MAD_F(0x07403fad) /* 0.453185729 */, 18 }, + + /* 6400 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 18 }, + /* 6401 */ { MAD_F(0x074105b8) /* 0.453374595 */, 18 }, + /* 6402 */ { MAD_F(0x074168bf) /* 0.453469036 */, 18 }, + /* 6403 */ { MAD_F(0x0741cbc8) /* 0.453563482 */, 18 }, + /* 6404 */ { MAD_F(0x07422ed2) /* 0.453657932 */, 18 }, + /* 6405 */ { MAD_F(0x074291dd) /* 0.453752388 */, 18 }, + /* 6406 */ { MAD_F(0x0742f4e9) /* 0.453846848 */, 18 }, + /* 6407 */ { MAD_F(0x074357f7) /* 0.453941314 */, 18 }, + /* 6408 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 18 }, + /* 6409 */ { MAD_F(0x07441e17) /* 0.454130259 */, 18 }, + /* 6410 */ { MAD_F(0x07448129) /* 0.454224739 */, 18 }, + /* 6411 */ { MAD_F(0x0744e43c) /* 0.454319224 */, 18 }, + /* 6412 */ { MAD_F(0x07454750) /* 0.454413714 */, 18 }, + /* 6413 */ { MAD_F(0x0745aa66) /* 0.454508209 */, 18 }, + /* 6414 */ { MAD_F(0x07460d7d) /* 0.454602708 */, 18 }, + /* 6415 */ { MAD_F(0x07467095) /* 0.454697213 */, 18 }, + + /* 6416 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 18 }, + /* 6417 */ { MAD_F(0x074736ca) /* 0.454886237 */, 18 }, + /* 6418 */ { MAD_F(0x074799e7) /* 0.454980756 */, 18 }, + /* 6419 */ { MAD_F(0x0747fd04) /* 0.455075281 */, 18 }, + /* 6420 */ { MAD_F(0x07486023) /* 0.455169810 */, 18 }, + /* 6421 */ { MAD_F(0x0748c344) /* 0.455264344 */, 18 }, + /* 6422 */ { MAD_F(0x07492665) /* 0.455358883 */, 18 }, + /* 6423 */ { MAD_F(0x07498988) /* 0.455453427 */, 18 }, + /* 6424 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 18 }, + /* 6425 */ { MAD_F(0x074a4fd2) /* 0.455642529 */, 18 }, + /* 6426 */ { MAD_F(0x074ab2f9) /* 0.455737088 */, 18 }, + /* 6427 */ { MAD_F(0x074b1621) /* 0.455831652 */, 18 }, + /* 6428 */ { MAD_F(0x074b794b) /* 0.455926220 */, 18 }, + /* 6429 */ { MAD_F(0x074bdc75) /* 0.456020793 */, 18 }, + /* 6430 */ { MAD_F(0x074c3fa1) /* 0.456115372 */, 18 }, + /* 6431 */ { MAD_F(0x074ca2cf) /* 0.456209955 */, 18 }, + + /* 6432 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 18 }, + /* 6433 */ { MAD_F(0x074d692e) /* 0.456399136 */, 18 }, + /* 6434 */ { MAD_F(0x074dcc5f) /* 0.456493733 */, 18 }, + /* 6435 */ { MAD_F(0x074e2f92) /* 0.456588336 */, 18 }, + /* 6436 */ { MAD_F(0x074e92c6) /* 0.456682944 */, 18 }, + /* 6437 */ { MAD_F(0x074ef5fb) /* 0.456777556 */, 18 }, + /* 6438 */ { MAD_F(0x074f5932) /* 0.456872174 */, 18 }, + /* 6439 */ { MAD_F(0x074fbc6a) /* 0.456966796 */, 18 }, + /* 6440 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 18 }, + /* 6441 */ { MAD_F(0x075082de) /* 0.457156056 */, 18 }, + /* 6442 */ { MAD_F(0x0750e61a) /* 0.457250693 */, 18 }, + /* 6443 */ { MAD_F(0x07514957) /* 0.457345335 */, 18 }, + /* 6444 */ { MAD_F(0x0751ac96) /* 0.457439981 */, 18 }, + /* 6445 */ { MAD_F(0x07520fd6) /* 0.457534633 */, 18 }, + /* 6446 */ { MAD_F(0x07527317) /* 0.457629290 */, 18 }, + /* 6447 */ { MAD_F(0x0752d659) /* 0.457723951 */, 18 }, + + /* 6448 */ { MAD_F(0x0753399d) /* 0.457818618 */, 18 }, + /* 6449 */ { MAD_F(0x07539ce2) /* 0.457913289 */, 18 }, + /* 6450 */ { MAD_F(0x07540029) /* 0.458007965 */, 18 }, + /* 6451 */ { MAD_F(0x07546371) /* 0.458102646 */, 18 }, + /* 6452 */ { MAD_F(0x0754c6ba) /* 0.458197332 */, 18 }, + /* 6453 */ { MAD_F(0x07552a04) /* 0.458292023 */, 18 }, + /* 6454 */ { MAD_F(0x07558d50) /* 0.458386719 */, 18 }, + /* 6455 */ { MAD_F(0x0755f09d) /* 0.458481420 */, 18 }, + /* 6456 */ { MAD_F(0x075653eb) /* 0.458576125 */, 18 }, + /* 6457 */ { MAD_F(0x0756b73b) /* 0.458670836 */, 18 }, + /* 6458 */ { MAD_F(0x07571a8c) /* 0.458765551 */, 18 }, + /* 6459 */ { MAD_F(0x07577dde) /* 0.458860271 */, 18 }, + /* 6460 */ { MAD_F(0x0757e131) /* 0.458954996 */, 18 }, + /* 6461 */ { MAD_F(0x07584486) /* 0.459049726 */, 18 }, + /* 6462 */ { MAD_F(0x0758a7dd) /* 0.459144461 */, 18 }, + /* 6463 */ { MAD_F(0x07590b34) /* 0.459239201 */, 18 }, + + /* 6464 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 18 }, + /* 6465 */ { MAD_F(0x0759d1e7) /* 0.459428695 */, 18 }, + /* 6466 */ { MAD_F(0x075a3542) /* 0.459523450 */, 18 }, + /* 6467 */ { MAD_F(0x075a989f) /* 0.459618209 */, 18 }, + /* 6468 */ { MAD_F(0x075afbfd) /* 0.459712973 */, 18 }, + /* 6469 */ { MAD_F(0x075b5f5d) /* 0.459807742 */, 18 }, + /* 6470 */ { MAD_F(0x075bc2bd) /* 0.459902516 */, 18 }, + /* 6471 */ { MAD_F(0x075c261f) /* 0.459997295 */, 18 }, + /* 6472 */ { MAD_F(0x075c8983) /* 0.460092079 */, 18 }, + /* 6473 */ { MAD_F(0x075cece7) /* 0.460186867 */, 18 }, + /* 6474 */ { MAD_F(0x075d504d) /* 0.460281661 */, 18 }, + /* 6475 */ { MAD_F(0x075db3b5) /* 0.460376459 */, 18 }, + /* 6476 */ { MAD_F(0x075e171d) /* 0.460471262 */, 18 }, + /* 6477 */ { MAD_F(0x075e7a87) /* 0.460566071 */, 18 }, + /* 6478 */ { MAD_F(0x075eddf2) /* 0.460660884 */, 18 }, + /* 6479 */ { MAD_F(0x075f415f) /* 0.460755701 */, 18 }, + + /* 6480 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 18 }, + /* 6481 */ { MAD_F(0x0760083b) /* 0.460945352 */, 18 }, + /* 6482 */ { MAD_F(0x07606bac) /* 0.461040184 */, 18 }, + /* 6483 */ { MAD_F(0x0760cf1e) /* 0.461135022 */, 18 }, + /* 6484 */ { MAD_F(0x07613291) /* 0.461229864 */, 18 }, + /* 6485 */ { MAD_F(0x07619605) /* 0.461324711 */, 18 }, + /* 6486 */ { MAD_F(0x0761f97b) /* 0.461419563 */, 18 }, + /* 6487 */ { MAD_F(0x07625cf2) /* 0.461514420 */, 18 }, + /* 6488 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 18 }, + /* 6489 */ { MAD_F(0x076323e3) /* 0.461704149 */, 18 }, + /* 6490 */ { MAD_F(0x0763875e) /* 0.461799020 */, 18 }, + /* 6491 */ { MAD_F(0x0763eadb) /* 0.461893897 */, 18 }, + /* 6492 */ { MAD_F(0x07644e58) /* 0.461988778 */, 18 }, + /* 6493 */ { MAD_F(0x0764b1d7) /* 0.462083664 */, 18 }, + /* 6494 */ { MAD_F(0x07651557) /* 0.462178555 */, 18 }, + /* 6495 */ { MAD_F(0x076578d8) /* 0.462273451 */, 18 }, + + /* 6496 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 18 }, + /* 6497 */ { MAD_F(0x07663fdf) /* 0.462463257 */, 18 }, + /* 6498 */ { MAD_F(0x0766a364) /* 0.462558168 */, 18 }, + /* 6499 */ { MAD_F(0x076706eb) /* 0.462653083 */, 18 }, + /* 6500 */ { MAD_F(0x07676a73) /* 0.462748003 */, 18 }, + /* 6501 */ { MAD_F(0x0767cdfc) /* 0.462842928 */, 18 }, + /* 6502 */ { MAD_F(0x07683187) /* 0.462937858 */, 18 }, + /* 6503 */ { MAD_F(0x07689513) /* 0.463032793 */, 18 }, + /* 6504 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 18 }, + /* 6505 */ { MAD_F(0x07695c2e) /* 0.463222678 */, 18 }, + /* 6506 */ { MAD_F(0x0769bfbe) /* 0.463317627 */, 18 }, + /* 6507 */ { MAD_F(0x076a234f) /* 0.463412581 */, 18 }, + /* 6508 */ { MAD_F(0x076a86e2) /* 0.463507540 */, 18 }, + /* 6509 */ { MAD_F(0x076aea75) /* 0.463602504 */, 18 }, + /* 6510 */ { MAD_F(0x076b4e0a) /* 0.463697473 */, 18 }, + /* 6511 */ { MAD_F(0x076bb1a1) /* 0.463792447 */, 18 }, + + /* 6512 */ { MAD_F(0x076c1538) /* 0.463887426 */, 18 }, + /* 6513 */ { MAD_F(0x076c78d1) /* 0.463982409 */, 18 }, + /* 6514 */ { MAD_F(0x076cdc6c) /* 0.464077398 */, 18 }, + /* 6515 */ { MAD_F(0x076d4007) /* 0.464172391 */, 18 }, + /* 6516 */ { MAD_F(0x076da3a4) /* 0.464267389 */, 18 }, + /* 6517 */ { MAD_F(0x076e0742) /* 0.464362392 */, 18 }, + /* 6518 */ { MAD_F(0x076e6ae2) /* 0.464457399 */, 18 }, + /* 6519 */ { MAD_F(0x076ece82) /* 0.464552412 */, 18 }, + /* 6520 */ { MAD_F(0x076f3224) /* 0.464647430 */, 18 }, + /* 6521 */ { MAD_F(0x076f95c8) /* 0.464742452 */, 18 }, + /* 6522 */ { MAD_F(0x076ff96c) /* 0.464837479 */, 18 }, + /* 6523 */ { MAD_F(0x07705d12) /* 0.464932511 */, 18 }, + /* 6524 */ { MAD_F(0x0770c0ba) /* 0.465027548 */, 18 }, + /* 6525 */ { MAD_F(0x07712462) /* 0.465122590 */, 18 }, + /* 6526 */ { MAD_F(0x0771880c) /* 0.465217637 */, 18 }, + /* 6527 */ { MAD_F(0x0771ebb7) /* 0.465312688 */, 18 }, + + /* 6528 */ { MAD_F(0x07724f64) /* 0.465407744 */, 18 }, + /* 6529 */ { MAD_F(0x0772b312) /* 0.465502806 */, 18 }, + /* 6530 */ { MAD_F(0x077316c1) /* 0.465597872 */, 18 }, + /* 6531 */ { MAD_F(0x07737a71) /* 0.465692943 */, 18 }, + /* 6532 */ { MAD_F(0x0773de23) /* 0.465788018 */, 18 }, + /* 6533 */ { MAD_F(0x077441d6) /* 0.465883099 */, 18 }, + /* 6534 */ { MAD_F(0x0774a58a) /* 0.465978184 */, 18 }, + /* 6535 */ { MAD_F(0x07750940) /* 0.466073275 */, 18 }, + /* 6536 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 18 }, + /* 6537 */ { MAD_F(0x0775d0af) /* 0.466263470 */, 18 }, + /* 6538 */ { MAD_F(0x07763468) /* 0.466358575 */, 18 }, + /* 6539 */ { MAD_F(0x07769823) /* 0.466453684 */, 18 }, + /* 6540 */ { MAD_F(0x0776fbdf) /* 0.466548799 */, 18 }, + /* 6541 */ { MAD_F(0x07775f9d) /* 0.466643918 */, 18 }, + /* 6542 */ { MAD_F(0x0777c35c) /* 0.466739043 */, 18 }, + /* 6543 */ { MAD_F(0x0778271c) /* 0.466834172 */, 18 }, + + /* 6544 */ { MAD_F(0x07788add) /* 0.466929306 */, 18 }, + /* 6545 */ { MAD_F(0x0778ee9f) /* 0.467024445 */, 18 }, + /* 6546 */ { MAD_F(0x07795263) /* 0.467119588 */, 18 }, + /* 6547 */ { MAD_F(0x0779b629) /* 0.467214737 */, 18 }, + /* 6548 */ { MAD_F(0x077a19ef) /* 0.467309890 */, 18 }, + /* 6549 */ { MAD_F(0x077a7db7) /* 0.467405048 */, 18 }, + /* 6550 */ { MAD_F(0x077ae180) /* 0.467500211 */, 18 }, + /* 6551 */ { MAD_F(0x077b454b) /* 0.467595379 */, 18 }, + /* 6552 */ { MAD_F(0x077ba916) /* 0.467690552 */, 18 }, + /* 6553 */ { MAD_F(0x077c0ce3) /* 0.467785729 */, 18 }, + /* 6554 */ { MAD_F(0x077c70b2) /* 0.467880912 */, 18 }, + /* 6555 */ { MAD_F(0x077cd481) /* 0.467976099 */, 18 }, + /* 6556 */ { MAD_F(0x077d3852) /* 0.468071291 */, 18 }, + /* 6557 */ { MAD_F(0x077d9c24) /* 0.468166488 */, 18 }, + /* 6558 */ { MAD_F(0x077dfff8) /* 0.468261690 */, 18 }, + /* 6559 */ { MAD_F(0x077e63cd) /* 0.468356896 */, 18 }, + + /* 6560 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 18 }, + /* 6561 */ { MAD_F(0x077f2b7a) /* 0.468547324 */, 18 }, + /* 6562 */ { MAD_F(0x077f8f53) /* 0.468642545 */, 18 }, + /* 6563 */ { MAD_F(0x077ff32d) /* 0.468737771 */, 18 }, + /* 6564 */ { MAD_F(0x07805708) /* 0.468833002 */, 18 }, + /* 6565 */ { MAD_F(0x0780bae5) /* 0.468928237 */, 18 }, + /* 6566 */ { MAD_F(0x07811ec3) /* 0.469023478 */, 18 }, + /* 6567 */ { MAD_F(0x078182a2) /* 0.469118723 */, 18 }, + /* 6568 */ { MAD_F(0x0781e683) /* 0.469213973 */, 18 }, + /* 6569 */ { MAD_F(0x07824a64) /* 0.469309228 */, 18 }, + /* 6570 */ { MAD_F(0x0782ae47) /* 0.469404488 */, 18 }, + /* 6571 */ { MAD_F(0x0783122c) /* 0.469499752 */, 18 }, + /* 6572 */ { MAD_F(0x07837612) /* 0.469595022 */, 18 }, + /* 6573 */ { MAD_F(0x0783d9f9) /* 0.469690296 */, 18 }, + /* 6574 */ { MAD_F(0x07843de1) /* 0.469785575 */, 18 }, + /* 6575 */ { MAD_F(0x0784a1ca) /* 0.469880859 */, 18 }, + + /* 6576 */ { MAD_F(0x078505b5) /* 0.469976148 */, 18 }, + /* 6577 */ { MAD_F(0x078569a2) /* 0.470071442 */, 18 }, + /* 6578 */ { MAD_F(0x0785cd8f) /* 0.470166740 */, 18 }, + /* 6579 */ { MAD_F(0x0786317e) /* 0.470262043 */, 18 }, + /* 6580 */ { MAD_F(0x0786956e) /* 0.470357351 */, 18 }, + /* 6581 */ { MAD_F(0x0786f95f) /* 0.470452664 */, 18 }, + /* 6582 */ { MAD_F(0x07875d52) /* 0.470547982 */, 18 }, + /* 6583 */ { MAD_F(0x0787c146) /* 0.470643305 */, 18 }, + /* 6584 */ { MAD_F(0x0788253b) /* 0.470738632 */, 18 }, + /* 6585 */ { MAD_F(0x07888932) /* 0.470833964 */, 18 }, + /* 6586 */ { MAD_F(0x0788ed2a) /* 0.470929301 */, 18 }, + /* 6587 */ { MAD_F(0x07895123) /* 0.471024643 */, 18 }, + /* 6588 */ { MAD_F(0x0789b51d) /* 0.471119990 */, 18 }, + /* 6589 */ { MAD_F(0x078a1919) /* 0.471215341 */, 18 }, + /* 6590 */ { MAD_F(0x078a7d16) /* 0.471310698 */, 18 }, + /* 6591 */ { MAD_F(0x078ae114) /* 0.471406059 */, 18 }, + + /* 6592 */ { MAD_F(0x078b4514) /* 0.471501425 */, 18 }, + /* 6593 */ { MAD_F(0x078ba915) /* 0.471596796 */, 18 }, + /* 6594 */ { MAD_F(0x078c0d17) /* 0.471692171 */, 18 }, + /* 6595 */ { MAD_F(0x078c711a) /* 0.471787552 */, 18 }, + /* 6596 */ { MAD_F(0x078cd51f) /* 0.471882937 */, 18 }, + /* 6597 */ { MAD_F(0x078d3925) /* 0.471978327 */, 18 }, + /* 6598 */ { MAD_F(0x078d9d2d) /* 0.472073722 */, 18 }, + /* 6599 */ { MAD_F(0x078e0135) /* 0.472169122 */, 18 }, + /* 6600 */ { MAD_F(0x078e653f) /* 0.472264527 */, 18 }, + /* 6601 */ { MAD_F(0x078ec94b) /* 0.472359936 */, 18 }, + /* 6602 */ { MAD_F(0x078f2d57) /* 0.472455350 */, 18 }, + /* 6603 */ { MAD_F(0x078f9165) /* 0.472550769 */, 18 }, + /* 6604 */ { MAD_F(0x078ff574) /* 0.472646193 */, 18 }, + /* 6605 */ { MAD_F(0x07905985) /* 0.472741622 */, 18 }, + /* 6606 */ { MAD_F(0x0790bd96) /* 0.472837055 */, 18 }, + /* 6607 */ { MAD_F(0x079121a9) /* 0.472932493 */, 18 }, + + /* 6608 */ { MAD_F(0x079185be) /* 0.473027937 */, 18 }, + /* 6609 */ { MAD_F(0x0791e9d3) /* 0.473123384 */, 18 }, + /* 6610 */ { MAD_F(0x07924dea) /* 0.473218837 */, 18 }, + /* 6611 */ { MAD_F(0x0792b202) /* 0.473314295 */, 18 }, + /* 6612 */ { MAD_F(0x0793161c) /* 0.473409757 */, 18 }, + /* 6613 */ { MAD_F(0x07937a37) /* 0.473505224 */, 18 }, + /* 6614 */ { MAD_F(0x0793de53) /* 0.473600696 */, 18 }, + /* 6615 */ { MAD_F(0x07944270) /* 0.473696173 */, 18 }, + /* 6616 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 18 }, + /* 6617 */ { MAD_F(0x07950aaf) /* 0.473887141 */, 18 }, + /* 6618 */ { MAD_F(0x07956ed0) /* 0.473982632 */, 18 }, + /* 6619 */ { MAD_F(0x0795d2f2) /* 0.474078128 */, 18 }, + /* 6620 */ { MAD_F(0x07963716) /* 0.474173629 */, 18 }, + /* 6621 */ { MAD_F(0x07969b3b) /* 0.474269135 */, 18 }, + /* 6622 */ { MAD_F(0x0796ff62) /* 0.474364645 */, 18 }, + /* 6623 */ { MAD_F(0x07976389) /* 0.474460161 */, 18 }, + + /* 6624 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 18 }, + /* 6625 */ { MAD_F(0x07982bdd) /* 0.474651205 */, 18 }, + /* 6626 */ { MAD_F(0x07989008) /* 0.474746735 */, 18 }, + /* 6627 */ { MAD_F(0x0798f435) /* 0.474842270 */, 18 }, + /* 6628 */ { MAD_F(0x07995863) /* 0.474937809 */, 18 }, + /* 6629 */ { MAD_F(0x0799bc92) /* 0.475033353 */, 18 }, + /* 6630 */ { MAD_F(0x079a20c3) /* 0.475128902 */, 18 }, + /* 6631 */ { MAD_F(0x079a84f5) /* 0.475224456 */, 18 }, + /* 6632 */ { MAD_F(0x079ae929) /* 0.475320014 */, 18 }, + /* 6633 */ { MAD_F(0x079b4d5d) /* 0.475415578 */, 18 }, + /* 6634 */ { MAD_F(0x079bb193) /* 0.475511146 */, 18 }, + /* 6635 */ { MAD_F(0x079c15ca) /* 0.475606719 */, 18 }, + /* 6636 */ { MAD_F(0x079c7a03) /* 0.475702296 */, 18 }, + /* 6637 */ { MAD_F(0x079cde3c) /* 0.475797879 */, 18 }, + /* 6638 */ { MAD_F(0x079d4277) /* 0.475893466 */, 18 }, + /* 6639 */ { MAD_F(0x079da6b4) /* 0.475989058 */, 18 }, + + /* 6640 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 18 }, + /* 6641 */ { MAD_F(0x079e6f30) /* 0.476180257 */, 18 }, + /* 6642 */ { MAD_F(0x079ed370) /* 0.476275863 */, 18 }, + /* 6643 */ { MAD_F(0x079f37b2) /* 0.476371475 */, 18 }, + /* 6644 */ { MAD_F(0x079f9bf5) /* 0.476467091 */, 18 }, + /* 6645 */ { MAD_F(0x07a00039) /* 0.476562712 */, 18 }, + /* 6646 */ { MAD_F(0x07a0647e) /* 0.476658338 */, 18 }, + /* 6647 */ { MAD_F(0x07a0c8c5) /* 0.476753968 */, 18 }, + /* 6648 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 18 }, + /* 6649 */ { MAD_F(0x07a19156) /* 0.476945243 */, 18 }, + /* 6650 */ { MAD_F(0x07a1f5a0) /* 0.477040888 */, 18 }, + /* 6651 */ { MAD_F(0x07a259ec) /* 0.477136538 */, 18 }, + /* 6652 */ { MAD_F(0x07a2be39) /* 0.477232193 */, 18 }, + /* 6653 */ { MAD_F(0x07a32287) /* 0.477327852 */, 18 }, + /* 6654 */ { MAD_F(0x07a386d7) /* 0.477423516 */, 18 }, + /* 6655 */ { MAD_F(0x07a3eb28) /* 0.477519185 */, 18 }, + + /* 6656 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 18 }, + /* 6657 */ { MAD_F(0x07a4b3ce) /* 0.477710537 */, 18 }, + /* 6658 */ { MAD_F(0x07a51822) /* 0.477806220 */, 18 }, + /* 6659 */ { MAD_F(0x07a57c78) /* 0.477901908 */, 18 }, + /* 6660 */ { MAD_F(0x07a5e0d0) /* 0.477997601 */, 18 }, + /* 6661 */ { MAD_F(0x07a64528) /* 0.478093299 */, 18 }, + /* 6662 */ { MAD_F(0x07a6a982) /* 0.478189001 */, 18 }, + /* 6663 */ { MAD_F(0x07a70ddd) /* 0.478284708 */, 18 }, + /* 6664 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 18 }, + /* 6665 */ { MAD_F(0x07a7d698) /* 0.478476137 */, 18 }, + /* 6666 */ { MAD_F(0x07a83af7) /* 0.478571858 */, 18 }, + /* 6667 */ { MAD_F(0x07a89f57) /* 0.478667585 */, 18 }, + /* 6668 */ { MAD_F(0x07a903b9) /* 0.478763316 */, 18 }, + /* 6669 */ { MAD_F(0x07a9681c) /* 0.478859052 */, 18 }, + /* 6670 */ { MAD_F(0x07a9cc80) /* 0.478954793 */, 18 }, + /* 6671 */ { MAD_F(0x07aa30e5) /* 0.479050538 */, 18 }, + + /* 6672 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 18 }, + /* 6673 */ { MAD_F(0x07aaf9b4) /* 0.479242043 */, 18 }, + /* 6674 */ { MAD_F(0x07ab5e1e) /* 0.479337803 */, 18 }, + /* 6675 */ { MAD_F(0x07abc288) /* 0.479433568 */, 18 }, + /* 6676 */ { MAD_F(0x07ac26f4) /* 0.479529337 */, 18 }, + /* 6677 */ { MAD_F(0x07ac8b61) /* 0.479625111 */, 18 }, + /* 6678 */ { MAD_F(0x07acefd0) /* 0.479720890 */, 18 }, + /* 6679 */ { MAD_F(0x07ad543f) /* 0.479816674 */, 18 }, + /* 6680 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 18 }, + /* 6681 */ { MAD_F(0x07ae1d23) /* 0.480008256 */, 18 }, + /* 6682 */ { MAD_F(0x07ae8196) /* 0.480104054 */, 18 }, + /* 6683 */ { MAD_F(0x07aee60b) /* 0.480199857 */, 18 }, + /* 6684 */ { MAD_F(0x07af4a81) /* 0.480295664 */, 18 }, + /* 6685 */ { MAD_F(0x07afaef9) /* 0.480391477 */, 18 }, + /* 6686 */ { MAD_F(0x07b01372) /* 0.480487294 */, 18 }, + /* 6687 */ { MAD_F(0x07b077ec) /* 0.480583116 */, 18 }, + + /* 6688 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 18 }, + /* 6689 */ { MAD_F(0x07b140e4) /* 0.480774774 */, 18 }, + /* 6690 */ { MAD_F(0x07b1a561) /* 0.480870611 */, 18 }, + /* 6691 */ { MAD_F(0x07b209e1) /* 0.480966452 */, 18 }, + /* 6692 */ { MAD_F(0x07b26e61) /* 0.481062298 */, 18 }, + /* 6693 */ { MAD_F(0x07b2d2e3) /* 0.481158148 */, 18 }, + /* 6694 */ { MAD_F(0x07b33766) /* 0.481254004 */, 18 }, + /* 6695 */ { MAD_F(0x07b39bea) /* 0.481349864 */, 18 }, + /* 6696 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 18 }, + /* 6697 */ { MAD_F(0x07b464f6) /* 0.481541598 */, 18 }, + /* 6698 */ { MAD_F(0x07b4c97e) /* 0.481637473 */, 18 }, + /* 6699 */ { MAD_F(0x07b52e08) /* 0.481733352 */, 18 }, + /* 6700 */ { MAD_F(0x07b59292) /* 0.481829236 */, 18 }, + /* 6701 */ { MAD_F(0x07b5f71e) /* 0.481925125 */, 18 }, + /* 6702 */ { MAD_F(0x07b65bac) /* 0.482021019 */, 18 }, + /* 6703 */ { MAD_F(0x07b6c03a) /* 0.482116917 */, 18 }, + + /* 6704 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 18 }, + /* 6705 */ { MAD_F(0x07b7895b) /* 0.482308728 */, 18 }, + /* 6706 */ { MAD_F(0x07b7eded) /* 0.482404640 */, 18 }, + /* 6707 */ { MAD_F(0x07b85281) /* 0.482500558 */, 18 }, + /* 6708 */ { MAD_F(0x07b8b716) /* 0.482596480 */, 18 }, + /* 6709 */ { MAD_F(0x07b91bac) /* 0.482692407 */, 18 }, + /* 6710 */ { MAD_F(0x07b98044) /* 0.482788339 */, 18 }, + /* 6711 */ { MAD_F(0x07b9e4dc) /* 0.482884275 */, 18 }, + /* 6712 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 18 }, + /* 6713 */ { MAD_F(0x07baae12) /* 0.483076162 */, 18 }, + /* 6714 */ { MAD_F(0x07bb12ae) /* 0.483172113 */, 18 }, + /* 6715 */ { MAD_F(0x07bb774c) /* 0.483268069 */, 18 }, + /* 6716 */ { MAD_F(0x07bbdbeb) /* 0.483364029 */, 18 }, + /* 6717 */ { MAD_F(0x07bc408c) /* 0.483459994 */, 18 }, + /* 6718 */ { MAD_F(0x07bca52d) /* 0.483555964 */, 18 }, + /* 6719 */ { MAD_F(0x07bd09d0) /* 0.483651939 */, 18 }, + + /* 6720 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 18 }, + /* 6721 */ { MAD_F(0x07bdd31a) /* 0.483843902 */, 18 }, + /* 6722 */ { MAD_F(0x07be37c1) /* 0.483939891 */, 18 }, + /* 6723 */ { MAD_F(0x07be9c69) /* 0.484035885 */, 18 }, + /* 6724 */ { MAD_F(0x07bf0113) /* 0.484131883 */, 18 }, + /* 6725 */ { MAD_F(0x07bf65bd) /* 0.484227886 */, 18 }, + /* 6726 */ { MAD_F(0x07bfca69) /* 0.484323894 */, 18 }, + /* 6727 */ { MAD_F(0x07c02f16) /* 0.484419907 */, 18 }, + /* 6728 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 18 }, + /* 6729 */ { MAD_F(0x07c0f875) /* 0.484611946 */, 18 }, + /* 6730 */ { MAD_F(0x07c15d26) /* 0.484707973 */, 18 }, + /* 6731 */ { MAD_F(0x07c1c1d8) /* 0.484804005 */, 18 }, + /* 6732 */ { MAD_F(0x07c2268b) /* 0.484900041 */, 18 }, + /* 6733 */ { MAD_F(0x07c28b40) /* 0.484996083 */, 18 }, + /* 6734 */ { MAD_F(0x07c2eff6) /* 0.485092128 */, 18 }, + /* 6735 */ { MAD_F(0x07c354ae) /* 0.485188179 */, 18 }, + + /* 6736 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 18 }, + /* 6737 */ { MAD_F(0x07c41e21) /* 0.485380295 */, 18 }, + /* 6738 */ { MAD_F(0x07c482dc) /* 0.485476360 */, 18 }, + /* 6739 */ { MAD_F(0x07c4e798) /* 0.485572430 */, 18 }, + /* 6740 */ { MAD_F(0x07c54c56) /* 0.485668504 */, 18 }, + /* 6741 */ { MAD_F(0x07c5b115) /* 0.485764583 */, 18 }, + /* 6742 */ { MAD_F(0x07c615d6) /* 0.485860667 */, 18 }, + /* 6743 */ { MAD_F(0x07c67a97) /* 0.485956756 */, 18 }, + /* 6744 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 18 }, + /* 6745 */ { MAD_F(0x07c7441e) /* 0.486148948 */, 18 }, + /* 6746 */ { MAD_F(0x07c7a8e4) /* 0.486245051 */, 18 }, + /* 6747 */ { MAD_F(0x07c80daa) /* 0.486341158 */, 18 }, + /* 6748 */ { MAD_F(0x07c87272) /* 0.486437271 */, 18 }, + /* 6749 */ { MAD_F(0x07c8d73c) /* 0.486533388 */, 18 }, + /* 6750 */ { MAD_F(0x07c93c06) /* 0.486629510 */, 18 }, + /* 6751 */ { MAD_F(0x07c9a0d2) /* 0.486725637 */, 18 }, + + /* 6752 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 18 }, + /* 6753 */ { MAD_F(0x07ca6a6d) /* 0.486917905 */, 18 }, + /* 6754 */ { MAD_F(0x07cacf3d) /* 0.487014045 */, 18 }, + /* 6755 */ { MAD_F(0x07cb340e) /* 0.487110191 */, 18 }, + /* 6756 */ { MAD_F(0x07cb98e0) /* 0.487206342 */, 18 }, + /* 6757 */ { MAD_F(0x07cbfdb4) /* 0.487302497 */, 18 }, + /* 6758 */ { MAD_F(0x07cc6288) /* 0.487398657 */, 18 }, + /* 6759 */ { MAD_F(0x07ccc75e) /* 0.487494821 */, 18 }, + /* 6760 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 18 }, + /* 6761 */ { MAD_F(0x07cd910e) /* 0.487687165 */, 18 }, + /* 6762 */ { MAD_F(0x07cdf5e8) /* 0.487783344 */, 18 }, + /* 6763 */ { MAD_F(0x07ce5ac3) /* 0.487879528 */, 18 }, + /* 6764 */ { MAD_F(0x07cebfa0) /* 0.487975716 */, 18 }, + /* 6765 */ { MAD_F(0x07cf247d) /* 0.488071909 */, 18 }, + /* 6766 */ { MAD_F(0x07cf895c) /* 0.488168107 */, 18 }, + /* 6767 */ { MAD_F(0x07cfee3c) /* 0.488264310 */, 18 }, + + /* 6768 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 18 }, + /* 6769 */ { MAD_F(0x07d0b801) /* 0.488456729 */, 18 }, + /* 6770 */ { MAD_F(0x07d11ce5) /* 0.488552946 */, 18 }, + /* 6771 */ { MAD_F(0x07d181ca) /* 0.488649167 */, 18 }, + /* 6772 */ { MAD_F(0x07d1e6b0) /* 0.488745394 */, 18 }, + /* 6773 */ { MAD_F(0x07d24b98) /* 0.488841625 */, 18 }, + /* 6774 */ { MAD_F(0x07d2b081) /* 0.488937860 */, 18 }, + /* 6775 */ { MAD_F(0x07d3156c) /* 0.489034101 */, 18 }, + /* 6776 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 18 }, + /* 6777 */ { MAD_F(0x07d3df44) /* 0.489226596 */, 18 }, + /* 6778 */ { MAD_F(0x07d44432) /* 0.489322851 */, 18 }, + /* 6779 */ { MAD_F(0x07d4a922) /* 0.489419110 */, 18 }, + /* 6780 */ { MAD_F(0x07d50e13) /* 0.489515375 */, 18 }, + /* 6781 */ { MAD_F(0x07d57305) /* 0.489611643 */, 18 }, + /* 6782 */ { MAD_F(0x07d5d7f8) /* 0.489707917 */, 18 }, + /* 6783 */ { MAD_F(0x07d63cec) /* 0.489804195 */, 18 }, + + /* 6784 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 18 }, + /* 6785 */ { MAD_F(0x07d706d9) /* 0.489996766 */, 18 }, + /* 6786 */ { MAD_F(0x07d76bd2) /* 0.490093059 */, 18 }, + /* 6787 */ { MAD_F(0x07d7d0cb) /* 0.490189356 */, 18 }, + /* 6788 */ { MAD_F(0x07d835c6) /* 0.490285658 */, 18 }, + /* 6789 */ { MAD_F(0x07d89ac2) /* 0.490381965 */, 18 }, + /* 6790 */ { MAD_F(0x07d8ffc0) /* 0.490478277 */, 18 }, + /* 6791 */ { MAD_F(0x07d964be) /* 0.490574593 */, 18 }, + /* 6792 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 18 }, + /* 6793 */ { MAD_F(0x07da2ebf) /* 0.490767239 */, 18 }, + /* 6794 */ { MAD_F(0x07da93c2) /* 0.490863570 */, 18 }, + /* 6795 */ { MAD_F(0x07daf8c6) /* 0.490959905 */, 18 }, + /* 6796 */ { MAD_F(0x07db5dcb) /* 0.491056245 */, 18 }, + /* 6797 */ { MAD_F(0x07dbc2d1) /* 0.491152589 */, 18 }, + /* 6798 */ { MAD_F(0x07dc27d9) /* 0.491248939 */, 18 }, + /* 6799 */ { MAD_F(0x07dc8ce1) /* 0.491345293 */, 18 }, + + /* 6800 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 18 }, + /* 6801 */ { MAD_F(0x07dd56f7) /* 0.491538015 */, 18 }, + /* 6802 */ { MAD_F(0x07ddbc04) /* 0.491634383 */, 18 }, + /* 6803 */ { MAD_F(0x07de2111) /* 0.491730756 */, 18 }, + /* 6804 */ { MAD_F(0x07de8621) /* 0.491827134 */, 18 }, + /* 6805 */ { MAD_F(0x07deeb31) /* 0.491923516 */, 18 }, + /* 6806 */ { MAD_F(0x07df5043) /* 0.492019903 */, 18 }, + /* 6807 */ { MAD_F(0x07dfb556) /* 0.492116295 */, 18 }, + /* 6808 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 18 }, + /* 6809 */ { MAD_F(0x07e07f80) /* 0.492309093 */, 18 }, + /* 6810 */ { MAD_F(0x07e0e496) /* 0.492405499 */, 18 }, + /* 6811 */ { MAD_F(0x07e149ae) /* 0.492501909 */, 18 }, + /* 6812 */ { MAD_F(0x07e1aec8) /* 0.492598325 */, 18 }, + /* 6813 */ { MAD_F(0x07e213e2) /* 0.492694745 */, 18 }, + /* 6814 */ { MAD_F(0x07e278fe) /* 0.492791170 */, 18 }, + /* 6815 */ { MAD_F(0x07e2de1b) /* 0.492887599 */, 18 }, + + /* 6816 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 18 }, + /* 6817 */ { MAD_F(0x07e3a859) /* 0.493080472 */, 18 }, + /* 6818 */ { MAD_F(0x07e40d7a) /* 0.493176916 */, 18 }, + /* 6819 */ { MAD_F(0x07e4729c) /* 0.493273365 */, 18 }, + /* 6820 */ { MAD_F(0x07e4d7c0) /* 0.493369818 */, 18 }, + /* 6821 */ { MAD_F(0x07e53ce4) /* 0.493466275 */, 18 }, + /* 6822 */ { MAD_F(0x07e5a20a) /* 0.493562738 */, 18 }, + /* 6823 */ { MAD_F(0x07e60732) /* 0.493659205 */, 18 }, + /* 6824 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 18 }, + /* 6825 */ { MAD_F(0x07e6d184) /* 0.493852154 */, 18 }, + /* 6826 */ { MAD_F(0x07e736af) /* 0.493948635 */, 18 }, + /* 6827 */ { MAD_F(0x07e79bdb) /* 0.494045122 */, 18 }, + /* 6828 */ { MAD_F(0x07e80109) /* 0.494141612 */, 18 }, + /* 6829 */ { MAD_F(0x07e86638) /* 0.494238108 */, 18 }, + /* 6830 */ { MAD_F(0x07e8cb68) /* 0.494334608 */, 18 }, + /* 6831 */ { MAD_F(0x07e93099) /* 0.494431113 */, 18 }, + + /* 6832 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 18 }, + /* 6833 */ { MAD_F(0x07e9fb00) /* 0.494624137 */, 18 }, + /* 6834 */ { MAD_F(0x07ea6035) /* 0.494720656 */, 18 }, + /* 6835 */ { MAD_F(0x07eac56b) /* 0.494817180 */, 18 }, + /* 6836 */ { MAD_F(0x07eb2aa3) /* 0.494913709 */, 18 }, + /* 6837 */ { MAD_F(0x07eb8fdc) /* 0.495010242 */, 18 }, + /* 6838 */ { MAD_F(0x07ebf516) /* 0.495106780 */, 18 }, + /* 6839 */ { MAD_F(0x07ec5a51) /* 0.495203322 */, 18 }, + /* 6840 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 18 }, + /* 6841 */ { MAD_F(0x07ed24cc) /* 0.495396422 */, 18 }, + /* 6842 */ { MAD_F(0x07ed8a0b) /* 0.495492978 */, 18 }, + /* 6843 */ { MAD_F(0x07edef4c) /* 0.495589540 */, 18 }, + /* 6844 */ { MAD_F(0x07ee548e) /* 0.495686106 */, 18 }, + /* 6845 */ { MAD_F(0x07eeb9d1) /* 0.495782677 */, 18 }, + /* 6846 */ { MAD_F(0x07ef1f15) /* 0.495879252 */, 18 }, + /* 6847 */ { MAD_F(0x07ef845b) /* 0.495975833 */, 18 }, + + /* 6848 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 18 }, + /* 6849 */ { MAD_F(0x07f04ee9) /* 0.496169007 */, 18 }, + /* 6850 */ { MAD_F(0x07f0b433) /* 0.496265602 */, 18 }, + /* 6851 */ { MAD_F(0x07f1197d) /* 0.496362201 */, 18 }, + /* 6852 */ { MAD_F(0x07f17ec9) /* 0.496458804 */, 18 }, + /* 6853 */ { MAD_F(0x07f1e416) /* 0.496555413 */, 18 }, + /* 6854 */ { MAD_F(0x07f24965) /* 0.496652026 */, 18 }, + /* 6855 */ { MAD_F(0x07f2aeb5) /* 0.496748644 */, 18 }, + /* 6856 */ { MAD_F(0x07f31405) /* 0.496845266 */, 18 }, + /* 6857 */ { MAD_F(0x07f37958) /* 0.496941894 */, 18 }, + /* 6858 */ { MAD_F(0x07f3deab) /* 0.497038526 */, 18 }, + /* 6859 */ { MAD_F(0x07f44400) /* 0.497135162 */, 18 }, + /* 6860 */ { MAD_F(0x07f4a956) /* 0.497231804 */, 18 }, + /* 6861 */ { MAD_F(0x07f50ead) /* 0.497328450 */, 18 }, + /* 6862 */ { MAD_F(0x07f57405) /* 0.497425100 */, 18 }, + /* 6863 */ { MAD_F(0x07f5d95f) /* 0.497521756 */, 18 }, + + /* 6864 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 18 }, + /* 6865 */ { MAD_F(0x07f6a416) /* 0.497715081 */, 18 }, + /* 6866 */ { MAD_F(0x07f70974) /* 0.497811750 */, 18 }, + /* 6867 */ { MAD_F(0x07f76ed3) /* 0.497908425 */, 18 }, + /* 6868 */ { MAD_F(0x07f7d433) /* 0.498005103 */, 18 }, + /* 6869 */ { MAD_F(0x07f83994) /* 0.498101787 */, 18 }, + /* 6870 */ { MAD_F(0x07f89ef7) /* 0.498198475 */, 18 }, + /* 6871 */ { MAD_F(0x07f9045a) /* 0.498295168 */, 18 }, + /* 6872 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 18 }, + /* 6873 */ { MAD_F(0x07f9cf26) /* 0.498488568 */, 18 }, + /* 6874 */ { MAD_F(0x07fa348e) /* 0.498585275 */, 18 }, + /* 6875 */ { MAD_F(0x07fa99f6) /* 0.498681987 */, 18 }, + /* 6876 */ { MAD_F(0x07faff60) /* 0.498778704 */, 18 }, + /* 6877 */ { MAD_F(0x07fb64cc) /* 0.498875425 */, 18 }, + /* 6878 */ { MAD_F(0x07fbca38) /* 0.498972150 */, 18 }, + /* 6879 */ { MAD_F(0x07fc2fa6) /* 0.499068881 */, 18 }, + + /* 6880 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 18 }, + /* 6881 */ { MAD_F(0x07fcfa86) /* 0.499262356 */, 18 }, + /* 6882 */ { MAD_F(0x07fd5ff8) /* 0.499359101 */, 18 }, + /* 6883 */ { MAD_F(0x07fdc56b) /* 0.499455850 */, 18 }, + /* 6884 */ { MAD_F(0x07fe2adf) /* 0.499552604 */, 18 }, + /* 6885 */ { MAD_F(0x07fe9054) /* 0.499649362 */, 18 }, + /* 6886 */ { MAD_F(0x07fef5cb) /* 0.499746126 */, 18 }, + /* 6887 */ { MAD_F(0x07ff5b43) /* 0.499842894 */, 18 }, + /* 6888 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 18 }, + /* 6889 */ { MAD_F(0x0400131b) /* 0.250018222 */, 19 }, + /* 6890 */ { MAD_F(0x040045d9) /* 0.250066613 */, 19 }, + /* 6891 */ { MAD_F(0x04007897) /* 0.250115006 */, 19 }, + /* 6892 */ { MAD_F(0x0400ab57) /* 0.250163402 */, 19 }, + /* 6893 */ { MAD_F(0x0400de16) /* 0.250211800 */, 19 }, + /* 6894 */ { MAD_F(0x040110d7) /* 0.250260200 */, 19 }, + /* 6895 */ { MAD_F(0x04014398) /* 0.250308603 */, 19 }, + + /* 6896 */ { MAD_F(0x04017659) /* 0.250357008 */, 19 }, + /* 6897 */ { MAD_F(0x0401a91c) /* 0.250405415 */, 19 }, + /* 6898 */ { MAD_F(0x0401dbdf) /* 0.250453825 */, 19 }, + /* 6899 */ { MAD_F(0x04020ea2) /* 0.250502237 */, 19 }, + /* 6900 */ { MAD_F(0x04024166) /* 0.250550652 */, 19 }, + /* 6901 */ { MAD_F(0x0402742b) /* 0.250599068 */, 19 }, + /* 6902 */ { MAD_F(0x0402a6f0) /* 0.250647488 */, 19 }, + /* 6903 */ { MAD_F(0x0402d9b6) /* 0.250695909 */, 19 }, + /* 6904 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 19 }, + /* 6905 */ { MAD_F(0x04033f44) /* 0.250792759 */, 19 }, + /* 6906 */ { MAD_F(0x0403720c) /* 0.250841187 */, 19 }, + /* 6907 */ { MAD_F(0x0403a4d5) /* 0.250889618 */, 19 }, + /* 6908 */ { MAD_F(0x0403d79e) /* 0.250938051 */, 19 }, + /* 6909 */ { MAD_F(0x04040a68) /* 0.250986487 */, 19 }, + /* 6910 */ { MAD_F(0x04043d32) /* 0.251034924 */, 19 }, + /* 6911 */ { MAD_F(0x04046ffd) /* 0.251083365 */, 19 }, + + /* 6912 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 19 }, + /* 6913 */ { MAD_F(0x0404d595) /* 0.251180252 */, 19 }, + /* 6914 */ { MAD_F(0x04050862) /* 0.251228699 */, 19 }, + /* 6915 */ { MAD_F(0x04053b30) /* 0.251277148 */, 19 }, + /* 6916 */ { MAD_F(0x04056dfe) /* 0.251325600 */, 19 }, + /* 6917 */ { MAD_F(0x0405a0cd) /* 0.251374054 */, 19 }, + /* 6918 */ { MAD_F(0x0405d39c) /* 0.251422511 */, 19 }, + /* 6919 */ { MAD_F(0x0406066c) /* 0.251470970 */, 19 }, + /* 6920 */ { MAD_F(0x0406393d) /* 0.251519431 */, 19 }, + /* 6921 */ { MAD_F(0x04066c0e) /* 0.251567894 */, 19 }, + /* 6922 */ { MAD_F(0x04069ee0) /* 0.251616360 */, 19 }, + /* 6923 */ { MAD_F(0x0406d1b3) /* 0.251664828 */, 19 }, + /* 6924 */ { MAD_F(0x04070486) /* 0.251713299 */, 19 }, + /* 6925 */ { MAD_F(0x0407375a) /* 0.251761772 */, 19 }, + /* 6926 */ { MAD_F(0x04076a2e) /* 0.251810247 */, 19 }, + /* 6927 */ { MAD_F(0x04079d03) /* 0.251858724 */, 19 }, + + /* 6928 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 19 }, + /* 6929 */ { MAD_F(0x040802af) /* 0.251955686 */, 19 }, + /* 6930 */ { MAD_F(0x04083586) /* 0.252004171 */, 19 }, + /* 6931 */ { MAD_F(0x0408685e) /* 0.252052658 */, 19 }, + /* 6932 */ { MAD_F(0x04089b36) /* 0.252101147 */, 19 }, + /* 6933 */ { MAD_F(0x0408ce0f) /* 0.252149638 */, 19 }, + /* 6934 */ { MAD_F(0x040900e8) /* 0.252198132 */, 19 }, + /* 6935 */ { MAD_F(0x040933c2) /* 0.252246628 */, 19 }, + /* 6936 */ { MAD_F(0x0409669d) /* 0.252295127 */, 19 }, + /* 6937 */ { MAD_F(0x04099978) /* 0.252343627 */, 19 }, + /* 6938 */ { MAD_F(0x0409cc54) /* 0.252392131 */, 19 }, + /* 6939 */ { MAD_F(0x0409ff31) /* 0.252440636 */, 19 }, + /* 6940 */ { MAD_F(0x040a320e) /* 0.252489144 */, 19 }, + /* 6941 */ { MAD_F(0x040a64ec) /* 0.252537654 */, 19 }, + /* 6942 */ { MAD_F(0x040a97cb) /* 0.252586166 */, 19 }, + /* 6943 */ { MAD_F(0x040acaaa) /* 0.252634681 */, 19 }, + + /* 6944 */ { MAD_F(0x040afd89) /* 0.252683198 */, 19 }, + /* 6945 */ { MAD_F(0x040b306a) /* 0.252731718 */, 19 }, + /* 6946 */ { MAD_F(0x040b634b) /* 0.252780240 */, 19 }, + /* 6947 */ { MAD_F(0x040b962c) /* 0.252828764 */, 19 }, + /* 6948 */ { MAD_F(0x040bc90e) /* 0.252877290 */, 19 }, + /* 6949 */ { MAD_F(0x040bfbf1) /* 0.252925819 */, 19 }, + /* 6950 */ { MAD_F(0x040c2ed5) /* 0.252974350 */, 19 }, + /* 6951 */ { MAD_F(0x040c61b9) /* 0.253022883 */, 19 }, + /* 6952 */ { MAD_F(0x040c949e) /* 0.253071419 */, 19 }, + /* 6953 */ { MAD_F(0x040cc783) /* 0.253119957 */, 19 }, + /* 6954 */ { MAD_F(0x040cfa69) /* 0.253168498 */, 19 }, + /* 6955 */ { MAD_F(0x040d2d4f) /* 0.253217040 */, 19 }, + /* 6956 */ { MAD_F(0x040d6037) /* 0.253265585 */, 19 }, + /* 6957 */ { MAD_F(0x040d931e) /* 0.253314133 */, 19 }, + /* 6958 */ { MAD_F(0x040dc607) /* 0.253362682 */, 19 }, + /* 6959 */ { MAD_F(0x040df8f0) /* 0.253411234 */, 19 }, + + /* 6960 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 19 }, + /* 6961 */ { MAD_F(0x040e5ec4) /* 0.253508345 */, 19 }, + /* 6962 */ { MAD_F(0x040e91af) /* 0.253556904 */, 19 }, + /* 6963 */ { MAD_F(0x040ec49b) /* 0.253605466 */, 19 }, + /* 6964 */ { MAD_F(0x040ef787) /* 0.253654029 */, 19 }, + /* 6965 */ { MAD_F(0x040f2a74) /* 0.253702595 */, 19 }, + /* 6966 */ { MAD_F(0x040f5d61) /* 0.253751164 */, 19 }, + /* 6967 */ { MAD_F(0x040f904f) /* 0.253799734 */, 19 }, + /* 6968 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 19 }, + /* 6969 */ { MAD_F(0x040ff62d) /* 0.253896883 */, 19 }, + /* 6970 */ { MAD_F(0x0410291d) /* 0.253945460 */, 19 }, + /* 6971 */ { MAD_F(0x04105c0e) /* 0.253994040 */, 19 }, + /* 6972 */ { MAD_F(0x04108eff) /* 0.254042622 */, 19 }, + /* 6973 */ { MAD_F(0x0410c1f1) /* 0.254091207 */, 19 }, + /* 6974 */ { MAD_F(0x0410f4e3) /* 0.254139794 */, 19 }, + /* 6975 */ { MAD_F(0x041127d6) /* 0.254188383 */, 19 }, + + /* 6976 */ { MAD_F(0x04115aca) /* 0.254236974 */, 19 }, + /* 6977 */ { MAD_F(0x04118dbe) /* 0.254285568 */, 19 }, + /* 6978 */ { MAD_F(0x0411c0b3) /* 0.254334165 */, 19 }, + /* 6979 */ { MAD_F(0x0411f3a9) /* 0.254382763 */, 19 }, + /* 6980 */ { MAD_F(0x0412269f) /* 0.254431364 */, 19 }, + /* 6981 */ { MAD_F(0x04125996) /* 0.254479967 */, 19 }, + /* 6982 */ { MAD_F(0x04128c8d) /* 0.254528572 */, 19 }, + /* 6983 */ { MAD_F(0x0412bf85) /* 0.254577180 */, 19 }, + /* 6984 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 19 }, + /* 6985 */ { MAD_F(0x04132577) /* 0.254674403 */, 19 }, + /* 6986 */ { MAD_F(0x04135871) /* 0.254723017 */, 19 }, + /* 6987 */ { MAD_F(0x04138b6c) /* 0.254771635 */, 19 }, + /* 6988 */ { MAD_F(0x0413be67) /* 0.254820254 */, 19 }, + /* 6989 */ { MAD_F(0x0413f163) /* 0.254868876 */, 19 }, + /* 6990 */ { MAD_F(0x0414245f) /* 0.254917500 */, 19 }, + /* 6991 */ { MAD_F(0x0414575c) /* 0.254966126 */, 19 }, + + /* 6992 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 19 }, + /* 6993 */ { MAD_F(0x0414bd58) /* 0.255063386 */, 19 }, + /* 6994 */ { MAD_F(0x0414f057) /* 0.255112019 */, 19 }, + /* 6995 */ { MAD_F(0x04152356) /* 0.255160655 */, 19 }, + /* 6996 */ { MAD_F(0x04155657) /* 0.255209292 */, 19 }, + /* 6997 */ { MAD_F(0x04158957) /* 0.255257933 */, 19 }, + /* 6998 */ { MAD_F(0x0415bc59) /* 0.255306575 */, 19 }, + /* 6999 */ { MAD_F(0x0415ef5b) /* 0.255355220 */, 19 }, + /* 7000 */ { MAD_F(0x0416225d) /* 0.255403867 */, 19 }, + /* 7001 */ { MAD_F(0x04165561) /* 0.255452517 */, 19 }, + /* 7002 */ { MAD_F(0x04168864) /* 0.255501169 */, 19 }, + /* 7003 */ { MAD_F(0x0416bb69) /* 0.255549823 */, 19 }, + /* 7004 */ { MAD_F(0x0416ee6e) /* 0.255598479 */, 19 }, + /* 7005 */ { MAD_F(0x04172174) /* 0.255647138 */, 19 }, + /* 7006 */ { MAD_F(0x0417547a) /* 0.255695799 */, 19 }, + /* 7007 */ { MAD_F(0x04178781) /* 0.255744463 */, 19 }, + + /* 7008 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 19 }, + /* 7009 */ { MAD_F(0x0417ed91) /* 0.255841796 */, 19 }, + /* 7010 */ { MAD_F(0x0418209a) /* 0.255890467 */, 19 }, + /* 7011 */ { MAD_F(0x041853a3) /* 0.255939139 */, 19 }, + /* 7012 */ { MAD_F(0x041886ad) /* 0.255987814 */, 19 }, + /* 7013 */ { MAD_F(0x0418b9b8) /* 0.256036492 */, 19 }, + /* 7014 */ { MAD_F(0x0418ecc3) /* 0.256085171 */, 19 }, + /* 7015 */ { MAD_F(0x04191fcf) /* 0.256133853 */, 19 }, + /* 7016 */ { MAD_F(0x041952dc) /* 0.256182537 */, 19 }, + /* 7017 */ { MAD_F(0x041985e9) /* 0.256231224 */, 19 }, + /* 7018 */ { MAD_F(0x0419b8f7) /* 0.256279913 */, 19 }, + /* 7019 */ { MAD_F(0x0419ec05) /* 0.256328604 */, 19 }, + /* 7020 */ { MAD_F(0x041a1f15) /* 0.256377297 */, 19 }, + /* 7021 */ { MAD_F(0x041a5224) /* 0.256425993 */, 19 }, + /* 7022 */ { MAD_F(0x041a8534) /* 0.256474691 */, 19 }, + /* 7023 */ { MAD_F(0x041ab845) /* 0.256523392 */, 19 }, + + /* 7024 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 19 }, + /* 7025 */ { MAD_F(0x041b1e69) /* 0.256620800 */, 19 }, + /* 7026 */ { MAD_F(0x041b517c) /* 0.256669507 */, 19 }, + /* 7027 */ { MAD_F(0x041b848f) /* 0.256718217 */, 19 }, + /* 7028 */ { MAD_F(0x041bb7a3) /* 0.256766929 */, 19 }, + /* 7029 */ { MAD_F(0x041beab8) /* 0.256815643 */, 19 }, + /* 7030 */ { MAD_F(0x041c1dcd) /* 0.256864359 */, 19 }, + /* 7031 */ { MAD_F(0x041c50e3) /* 0.256913078 */, 19 }, + /* 7032 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 19 }, + /* 7033 */ { MAD_F(0x041cb711) /* 0.257010523 */, 19 }, + /* 7034 */ { MAD_F(0x041cea28) /* 0.257059249 */, 19 }, + /* 7035 */ { MAD_F(0x041d1d41) /* 0.257107977 */, 19 }, + /* 7036 */ { MAD_F(0x041d505a) /* 0.257156708 */, 19 }, + /* 7037 */ { MAD_F(0x041d8373) /* 0.257205440 */, 19 }, + /* 7038 */ { MAD_F(0x041db68e) /* 0.257254175 */, 19 }, + /* 7039 */ { MAD_F(0x041de9a8) /* 0.257302913 */, 19 }, + + /* 7040 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 19 }, + /* 7041 */ { MAD_F(0x041e4fe0) /* 0.257400394 */, 19 }, + /* 7042 */ { MAD_F(0x041e82fd) /* 0.257449139 */, 19 }, + /* 7043 */ { MAD_F(0x041eb61a) /* 0.257497885 */, 19 }, + /* 7044 */ { MAD_F(0x041ee938) /* 0.257546634 */, 19 }, + /* 7045 */ { MAD_F(0x041f1c57) /* 0.257595386 */, 19 }, + /* 7046 */ { MAD_F(0x041f4f76) /* 0.257644139 */, 19 }, + /* 7047 */ { MAD_F(0x041f8296) /* 0.257692895 */, 19 }, + /* 7048 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 19 }, + /* 7049 */ { MAD_F(0x041fe8d7) /* 0.257790414 */, 19 }, + /* 7050 */ { MAD_F(0x04201bf9) /* 0.257839176 */, 19 }, + /* 7051 */ { MAD_F(0x04204f1b) /* 0.257887941 */, 19 }, + /* 7052 */ { MAD_F(0x0420823e) /* 0.257936709 */, 19 }, + /* 7053 */ { MAD_F(0x0420b561) /* 0.257985478 */, 19 }, + /* 7054 */ { MAD_F(0x0420e885) /* 0.258034250 */, 19 }, + /* 7055 */ { MAD_F(0x04211baa) /* 0.258083025 */, 19 }, + + /* 7056 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 19 }, + /* 7057 */ { MAD_F(0x042181f6) /* 0.258180580 */, 19 }, + /* 7058 */ { MAD_F(0x0421b51c) /* 0.258229361 */, 19 }, + /* 7059 */ { MAD_F(0x0421e843) /* 0.258278145 */, 19 }, + /* 7060 */ { MAD_F(0x04221b6b) /* 0.258326931 */, 19 }, + /* 7061 */ { MAD_F(0x04224e94) /* 0.258375719 */, 19 }, + /* 7062 */ { MAD_F(0x042281bd) /* 0.258424509 */, 19 }, + /* 7063 */ { MAD_F(0x0422b4e6) /* 0.258473302 */, 19 }, + /* 7064 */ { MAD_F(0x0422e811) /* 0.258522097 */, 19 }, + /* 7065 */ { MAD_F(0x04231b3c) /* 0.258570894 */, 19 }, + /* 7066 */ { MAD_F(0x04234e67) /* 0.258619694 */, 19 }, + /* 7067 */ { MAD_F(0x04238193) /* 0.258668496 */, 19 }, + /* 7068 */ { MAD_F(0x0423b4c0) /* 0.258717300 */, 19 }, + /* 7069 */ { MAD_F(0x0423e7ee) /* 0.258766106 */, 19 }, + /* 7070 */ { MAD_F(0x04241b1c) /* 0.258814915 */, 19 }, + /* 7071 */ { MAD_F(0x04244e4a) /* 0.258863726 */, 19 }, + + /* 7072 */ { MAD_F(0x04248179) /* 0.258912540 */, 19 }, + /* 7073 */ { MAD_F(0x0424b4a9) /* 0.258961356 */, 19 }, + /* 7074 */ { MAD_F(0x0424e7da) /* 0.259010174 */, 19 }, + /* 7075 */ { MAD_F(0x04251b0b) /* 0.259058994 */, 19 }, + /* 7076 */ { MAD_F(0x04254e3d) /* 0.259107817 */, 19 }, + /* 7077 */ { MAD_F(0x0425816f) /* 0.259156642 */, 19 }, + /* 7078 */ { MAD_F(0x0425b4a2) /* 0.259205469 */, 19 }, + /* 7079 */ { MAD_F(0x0425e7d6) /* 0.259254298 */, 19 }, + /* 7080 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 19 }, + /* 7081 */ { MAD_F(0x04264e3f) /* 0.259351964 */, 19 }, + /* 7082 */ { MAD_F(0x04268174) /* 0.259400801 */, 19 }, + /* 7083 */ { MAD_F(0x0426b4aa) /* 0.259449639 */, 19 }, + /* 7084 */ { MAD_F(0x0426e7e1) /* 0.259498480 */, 19 }, + /* 7085 */ { MAD_F(0x04271b18) /* 0.259547324 */, 19 }, + /* 7086 */ { MAD_F(0x04274e50) /* 0.259596169 */, 19 }, + /* 7087 */ { MAD_F(0x04278188) /* 0.259645017 */, 19 }, + + /* 7088 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 19 }, + /* 7089 */ { MAD_F(0x0427e7fb) /* 0.259742720 */, 19 }, + /* 7090 */ { MAD_F(0x04281b36) /* 0.259791575 */, 19 }, + /* 7091 */ { MAD_F(0x04284e71) /* 0.259840432 */, 19 }, + /* 7092 */ { MAD_F(0x042881ac) /* 0.259889291 */, 19 }, + /* 7093 */ { MAD_F(0x0428b4e8) /* 0.259938153 */, 19 }, + /* 7094 */ { MAD_F(0x0428e825) /* 0.259987017 */, 19 }, + /* 7095 */ { MAD_F(0x04291b63) /* 0.260035883 */, 19 }, + /* 7096 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 19 }, + /* 7097 */ { MAD_F(0x042981df) /* 0.260133623 */, 19 }, + /* 7098 */ { MAD_F(0x0429b51f) /* 0.260182496 */, 19 }, + /* 7099 */ { MAD_F(0x0429e85f) /* 0.260231372 */, 19 }, + /* 7100 */ { MAD_F(0x042a1b9f) /* 0.260280249 */, 19 }, + /* 7101 */ { MAD_F(0x042a4ee0) /* 0.260329129 */, 19 }, + /* 7102 */ { MAD_F(0x042a8222) /* 0.260378012 */, 19 }, + /* 7103 */ { MAD_F(0x042ab564) /* 0.260426896 */, 19 }, + + /* 7104 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 19 }, + /* 7105 */ { MAD_F(0x042b1beb) /* 0.260524673 */, 19 }, + /* 7106 */ { MAD_F(0x042b4f2f) /* 0.260573564 */, 19 }, + /* 7107 */ { MAD_F(0x042b8274) /* 0.260622458 */, 19 }, + /* 7108 */ { MAD_F(0x042bb5ba) /* 0.260671354 */, 19 }, + /* 7109 */ { MAD_F(0x042be900) /* 0.260720252 */, 19 }, + /* 7110 */ { MAD_F(0x042c1c46) /* 0.260769153 */, 19 }, + /* 7111 */ { MAD_F(0x042c4f8e) /* 0.260818056 */, 19 }, + /* 7112 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 19 }, + /* 7113 */ { MAD_F(0x042cb61e) /* 0.260915869 */, 19 }, + /* 7114 */ { MAD_F(0x042ce967) /* 0.260964779 */, 19 }, + /* 7115 */ { MAD_F(0x042d1cb1) /* 0.261013691 */, 19 }, + /* 7116 */ { MAD_F(0x042d4ffb) /* 0.261062606 */, 19 }, + /* 7117 */ { MAD_F(0x042d8346) /* 0.261111522 */, 19 }, + /* 7118 */ { MAD_F(0x042db692) /* 0.261160441 */, 19 }, + /* 7119 */ { MAD_F(0x042de9de) /* 0.261209363 */, 19 }, + + /* 7120 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 19 }, + /* 7121 */ { MAD_F(0x042e5078) /* 0.261307212 */, 19 }, + /* 7122 */ { MAD_F(0x042e83c6) /* 0.261356140 */, 19 }, + /* 7123 */ { MAD_F(0x042eb715) /* 0.261405071 */, 19 }, + /* 7124 */ { MAD_F(0x042eea64) /* 0.261454004 */, 19 }, + /* 7125 */ { MAD_F(0x042f1db4) /* 0.261502939 */, 19 }, + /* 7126 */ { MAD_F(0x042f5105) /* 0.261551876 */, 19 }, + /* 7127 */ { MAD_F(0x042f8456) /* 0.261600816 */, 19 }, + /* 7128 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 19 }, + /* 7129 */ { MAD_F(0x042feafa) /* 0.261698702 */, 19 }, + /* 7130 */ { MAD_F(0x04301e4d) /* 0.261747649 */, 19 }, + /* 7131 */ { MAD_F(0x043051a1) /* 0.261796597 */, 19 }, + /* 7132 */ { MAD_F(0x043084f5) /* 0.261845548 */, 19 }, + /* 7133 */ { MAD_F(0x0430b84a) /* 0.261894502 */, 19 }, + /* 7134 */ { MAD_F(0x0430eb9f) /* 0.261943458 */, 19 }, + /* 7135 */ { MAD_F(0x04311ef5) /* 0.261992416 */, 19 }, + + /* 7136 */ { MAD_F(0x0431524c) /* 0.262041376 */, 19 }, + /* 7137 */ { MAD_F(0x043185a3) /* 0.262090338 */, 19 }, + /* 7138 */ { MAD_F(0x0431b8fb) /* 0.262139303 */, 19 }, + /* 7139 */ { MAD_F(0x0431ec54) /* 0.262188270 */, 19 }, + /* 7140 */ { MAD_F(0x04321fad) /* 0.262237240 */, 19 }, + /* 7141 */ { MAD_F(0x04325306) /* 0.262286211 */, 19 }, + /* 7142 */ { MAD_F(0x04328661) /* 0.262335185 */, 19 }, + /* 7143 */ { MAD_F(0x0432b9bc) /* 0.262384162 */, 19 }, + /* 7144 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 19 }, + /* 7145 */ { MAD_F(0x04332074) /* 0.262482121 */, 19 }, + /* 7146 */ { MAD_F(0x043353d0) /* 0.262531104 */, 19 }, + /* 7147 */ { MAD_F(0x0433872e) /* 0.262580089 */, 19 }, + /* 7148 */ { MAD_F(0x0433ba8c) /* 0.262629077 */, 19 }, + /* 7149 */ { MAD_F(0x0433edea) /* 0.262678067 */, 19 }, + /* 7150 */ { MAD_F(0x0434214a) /* 0.262727059 */, 19 }, + /* 7151 */ { MAD_F(0x043454aa) /* 0.262776054 */, 19 }, + + /* 7152 */ { MAD_F(0x0434880a) /* 0.262825051 */, 19 }, + /* 7153 */ { MAD_F(0x0434bb6b) /* 0.262874050 */, 19 }, + /* 7154 */ { MAD_F(0x0434eecd) /* 0.262923051 */, 19 }, + /* 7155 */ { MAD_F(0x0435222f) /* 0.262972055 */, 19 }, + /* 7156 */ { MAD_F(0x04355592) /* 0.263021061 */, 19 }, + /* 7157 */ { MAD_F(0x043588f6) /* 0.263070069 */, 19 }, + /* 7158 */ { MAD_F(0x0435bc5a) /* 0.263119079 */, 19 }, + /* 7159 */ { MAD_F(0x0435efbf) /* 0.263168092 */, 19 }, + /* 7160 */ { MAD_F(0x04362324) /* 0.263217107 */, 19 }, + /* 7161 */ { MAD_F(0x0436568a) /* 0.263266125 */, 19 }, + /* 7162 */ { MAD_F(0x043689f1) /* 0.263315144 */, 19 }, + /* 7163 */ { MAD_F(0x0436bd58) /* 0.263364166 */, 19 }, + /* 7164 */ { MAD_F(0x0436f0c0) /* 0.263413191 */, 19 }, + /* 7165 */ { MAD_F(0x04372428) /* 0.263462217 */, 19 }, + /* 7166 */ { MAD_F(0x04375791) /* 0.263511246 */, 19 }, + /* 7167 */ { MAD_F(0x04378afb) /* 0.263560277 */, 19 }, + + /* 7168 */ { MAD_F(0x0437be65) /* 0.263609310 */, 19 }, + /* 7169 */ { MAD_F(0x0437f1d0) /* 0.263658346 */, 19 }, + /* 7170 */ { MAD_F(0x0438253c) /* 0.263707384 */, 19 }, + /* 7171 */ { MAD_F(0x043858a8) /* 0.263756424 */, 19 }, + /* 7172 */ { MAD_F(0x04388c14) /* 0.263805466 */, 19 }, + /* 7173 */ { MAD_F(0x0438bf82) /* 0.263854511 */, 19 }, + /* 7174 */ { MAD_F(0x0438f2f0) /* 0.263903558 */, 19 }, + /* 7175 */ { MAD_F(0x0439265e) /* 0.263952607 */, 19 }, + /* 7176 */ { MAD_F(0x043959cd) /* 0.264001659 */, 19 }, + /* 7177 */ { MAD_F(0x04398d3d) /* 0.264050713 */, 19 }, + /* 7178 */ { MAD_F(0x0439c0ae) /* 0.264099769 */, 19 }, + /* 7179 */ { MAD_F(0x0439f41f) /* 0.264148827 */, 19 }, + /* 7180 */ { MAD_F(0x043a2790) /* 0.264197888 */, 19 }, + /* 7181 */ { MAD_F(0x043a5b02) /* 0.264246951 */, 19 }, + /* 7182 */ { MAD_F(0x043a8e75) /* 0.264296016 */, 19 }, + /* 7183 */ { MAD_F(0x043ac1e9) /* 0.264345084 */, 19 }, + + /* 7184 */ { MAD_F(0x043af55d) /* 0.264394153 */, 19 }, + /* 7185 */ { MAD_F(0x043b28d2) /* 0.264443225 */, 19 }, + /* 7186 */ { MAD_F(0x043b5c47) /* 0.264492300 */, 19 }, + /* 7187 */ { MAD_F(0x043b8fbd) /* 0.264541376 */, 19 }, + /* 7188 */ { MAD_F(0x043bc333) /* 0.264590455 */, 19 }, + /* 7189 */ { MAD_F(0x043bf6aa) /* 0.264639536 */, 19 }, + /* 7190 */ { MAD_F(0x043c2a22) /* 0.264688620 */, 19 }, + /* 7191 */ { MAD_F(0x043c5d9a) /* 0.264737706 */, 19 }, + /* 7192 */ { MAD_F(0x043c9113) /* 0.264786794 */, 19 }, + /* 7193 */ { MAD_F(0x043cc48d) /* 0.264835884 */, 19 }, + /* 7194 */ { MAD_F(0x043cf807) /* 0.264884976 */, 19 }, + /* 7195 */ { MAD_F(0x043d2b82) /* 0.264934071 */, 19 }, + /* 7196 */ { MAD_F(0x043d5efd) /* 0.264983168 */, 19 }, + /* 7197 */ { MAD_F(0x043d9279) /* 0.265032268 */, 19 }, + /* 7198 */ { MAD_F(0x043dc5f6) /* 0.265081369 */, 19 }, + /* 7199 */ { MAD_F(0x043df973) /* 0.265130473 */, 19 }, + + /* 7200 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 19 }, + /* 7201 */ { MAD_F(0x043e6070) /* 0.265228688 */, 19 }, + /* 7202 */ { MAD_F(0x043e93ef) /* 0.265277799 */, 19 }, + /* 7203 */ { MAD_F(0x043ec76e) /* 0.265326912 */, 19 }, + /* 7204 */ { MAD_F(0x043efaef) /* 0.265376027 */, 19 }, + /* 7205 */ { MAD_F(0x043f2e6f) /* 0.265425145 */, 19 }, + /* 7206 */ { MAD_F(0x043f61f1) /* 0.265474264 */, 19 }, + /* 7207 */ { MAD_F(0x043f9573) /* 0.265523387 */, 19 }, + /* 7208 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 19 }, + /* 7209 */ { MAD_F(0x043ffc79) /* 0.265621638 */, 19 }, + /* 7210 */ { MAD_F(0x04402ffd) /* 0.265670766 */, 19 }, + /* 7211 */ { MAD_F(0x04406382) /* 0.265719898 */, 19 }, + /* 7212 */ { MAD_F(0x04409707) /* 0.265769031 */, 19 }, + /* 7213 */ { MAD_F(0x0440ca8d) /* 0.265818167 */, 19 }, + /* 7214 */ { MAD_F(0x0440fe13) /* 0.265867305 */, 19 }, + /* 7215 */ { MAD_F(0x0441319a) /* 0.265916445 */, 19 }, + + /* 7216 */ { MAD_F(0x04416522) /* 0.265965588 */, 19 }, + /* 7217 */ { MAD_F(0x044198aa) /* 0.266014732 */, 19 }, + /* 7218 */ { MAD_F(0x0441cc33) /* 0.266063880 */, 19 }, + /* 7219 */ { MAD_F(0x0441ffbc) /* 0.266113029 */, 19 }, + /* 7220 */ { MAD_F(0x04423346) /* 0.266162181 */, 19 }, + /* 7221 */ { MAD_F(0x044266d1) /* 0.266211334 */, 19 }, + /* 7222 */ { MAD_F(0x04429a5c) /* 0.266260491 */, 19 }, + /* 7223 */ { MAD_F(0x0442cde8) /* 0.266309649 */, 19 }, + /* 7224 */ { MAD_F(0x04430174) /* 0.266358810 */, 19 }, + /* 7225 */ { MAD_F(0x04433501) /* 0.266407973 */, 19 }, + /* 7226 */ { MAD_F(0x0443688f) /* 0.266457138 */, 19 }, + /* 7227 */ { MAD_F(0x04439c1d) /* 0.266506305 */, 19 }, + /* 7228 */ { MAD_F(0x0443cfac) /* 0.266555475 */, 19 }, + /* 7229 */ { MAD_F(0x0444033c) /* 0.266604647 */, 19 }, + /* 7230 */ { MAD_F(0x044436cc) /* 0.266653822 */, 19 }, + /* 7231 */ { MAD_F(0x04446a5d) /* 0.266702998 */, 19 }, + + /* 7232 */ { MAD_F(0x04449dee) /* 0.266752177 */, 19 }, + /* 7233 */ { MAD_F(0x0444d180) /* 0.266801358 */, 19 }, + /* 7234 */ { MAD_F(0x04450513) /* 0.266850541 */, 19 }, + /* 7235 */ { MAD_F(0x044538a6) /* 0.266899727 */, 19 }, + /* 7236 */ { MAD_F(0x04456c39) /* 0.266948915 */, 19 }, + /* 7237 */ { MAD_F(0x04459fce) /* 0.266998105 */, 19 }, + /* 7238 */ { MAD_F(0x0445d363) /* 0.267047298 */, 19 }, + /* 7239 */ { MAD_F(0x044606f8) /* 0.267096492 */, 19 }, + /* 7240 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 19 }, + /* 7241 */ { MAD_F(0x04466e25) /* 0.267194888 */, 19 }, + /* 7242 */ { MAD_F(0x0446a1bd) /* 0.267244090 */, 19 }, + /* 7243 */ { MAD_F(0x0446d555) /* 0.267293294 */, 19 }, + /* 7244 */ { MAD_F(0x044708ee) /* 0.267342500 */, 19 }, + /* 7245 */ { MAD_F(0x04473c87) /* 0.267391708 */, 19 }, + /* 7246 */ { MAD_F(0x04477021) /* 0.267440919 */, 19 }, + /* 7247 */ { MAD_F(0x0447a3bb) /* 0.267490131 */, 19 }, + + /* 7248 */ { MAD_F(0x0447d756) /* 0.267539347 */, 19 }, + /* 7249 */ { MAD_F(0x04480af2) /* 0.267588564 */, 19 }, + /* 7250 */ { MAD_F(0x04483e8e) /* 0.267637783 */, 19 }, + /* 7251 */ { MAD_F(0x0448722b) /* 0.267687005 */, 19 }, + /* 7252 */ { MAD_F(0x0448a5c9) /* 0.267736229 */, 19 }, + /* 7253 */ { MAD_F(0x0448d967) /* 0.267785456 */, 19 }, + /* 7254 */ { MAD_F(0x04490d05) /* 0.267834685 */, 19 }, + /* 7255 */ { MAD_F(0x044940a5) /* 0.267883915 */, 19 }, + /* 7256 */ { MAD_F(0x04497445) /* 0.267933149 */, 19 }, + /* 7257 */ { MAD_F(0x0449a7e5) /* 0.267982384 */, 19 }, + /* 7258 */ { MAD_F(0x0449db86) /* 0.268031622 */, 19 }, + /* 7259 */ { MAD_F(0x044a0f28) /* 0.268080862 */, 19 }, + /* 7260 */ { MAD_F(0x044a42ca) /* 0.268130104 */, 19 }, + /* 7261 */ { MAD_F(0x044a766d) /* 0.268179349 */, 19 }, + /* 7262 */ { MAD_F(0x044aaa11) /* 0.268228595 */, 19 }, + /* 7263 */ { MAD_F(0x044addb5) /* 0.268277844 */, 19 }, + + /* 7264 */ { MAD_F(0x044b115a) /* 0.268327096 */, 19 }, + /* 7265 */ { MAD_F(0x044b44ff) /* 0.268376349 */, 19 }, + /* 7266 */ { MAD_F(0x044b78a5) /* 0.268425605 */, 19 }, + /* 7267 */ { MAD_F(0x044bac4c) /* 0.268474863 */, 19 }, + /* 7268 */ { MAD_F(0x044bdff3) /* 0.268524123 */, 19 }, + /* 7269 */ { MAD_F(0x044c139b) /* 0.268573386 */, 19 }, + /* 7270 */ { MAD_F(0x044c4743) /* 0.268622651 */, 19 }, + /* 7271 */ { MAD_F(0x044c7aec) /* 0.268671918 */, 19 }, + /* 7272 */ { MAD_F(0x044cae96) /* 0.268721187 */, 19 }, + /* 7273 */ { MAD_F(0x044ce240) /* 0.268770459 */, 19 }, + /* 7274 */ { MAD_F(0x044d15eb) /* 0.268819733 */, 19 }, + /* 7275 */ { MAD_F(0x044d4997) /* 0.268869009 */, 19 }, + /* 7276 */ { MAD_F(0x044d7d43) /* 0.268918287 */, 19 }, + /* 7277 */ { MAD_F(0x044db0ef) /* 0.268967568 */, 19 }, + /* 7278 */ { MAD_F(0x044de49d) /* 0.269016851 */, 19 }, + /* 7279 */ { MAD_F(0x044e184b) /* 0.269066136 */, 19 }, + + /* 7280 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 19 }, + /* 7281 */ { MAD_F(0x044e7fa8) /* 0.269164713 */, 19 }, + /* 7282 */ { MAD_F(0x044eb358) /* 0.269214005 */, 19 }, + /* 7283 */ { MAD_F(0x044ee708) /* 0.269263299 */, 19 }, + /* 7284 */ { MAD_F(0x044f1ab9) /* 0.269312595 */, 19 }, + /* 7285 */ { MAD_F(0x044f4e6b) /* 0.269361894 */, 19 }, + /* 7286 */ { MAD_F(0x044f821d) /* 0.269411195 */, 19 }, + /* 7287 */ { MAD_F(0x044fb5cf) /* 0.269460498 */, 19 }, + /* 7288 */ { MAD_F(0x044fe983) /* 0.269509804 */, 19 }, + /* 7289 */ { MAD_F(0x04501d37) /* 0.269559111 */, 19 }, + /* 7290 */ { MAD_F(0x045050eb) /* 0.269608421 */, 19 }, + /* 7291 */ { MAD_F(0x045084a0) /* 0.269657734 */, 19 }, + /* 7292 */ { MAD_F(0x0450b856) /* 0.269707048 */, 19 }, + /* 7293 */ { MAD_F(0x0450ec0d) /* 0.269756365 */, 19 }, + /* 7294 */ { MAD_F(0x04511fc4) /* 0.269805684 */, 19 }, + /* 7295 */ { MAD_F(0x0451537b) /* 0.269855005 */, 19 }, + + /* 7296 */ { MAD_F(0x04518733) /* 0.269904329 */, 19 }, + /* 7297 */ { MAD_F(0x0451baec) /* 0.269953654 */, 19 }, + /* 7298 */ { MAD_F(0x0451eea5) /* 0.270002982 */, 19 }, + /* 7299 */ { MAD_F(0x0452225f) /* 0.270052313 */, 19 }, + /* 7300 */ { MAD_F(0x0452561a) /* 0.270101645 */, 19 }, + /* 7301 */ { MAD_F(0x045289d5) /* 0.270150980 */, 19 }, + /* 7302 */ { MAD_F(0x0452bd91) /* 0.270200317 */, 19 }, + /* 7303 */ { MAD_F(0x0452f14d) /* 0.270249656 */, 19 }, + /* 7304 */ { MAD_F(0x0453250a) /* 0.270298998 */, 19 }, + /* 7305 */ { MAD_F(0x045358c8) /* 0.270348341 */, 19 }, + /* 7306 */ { MAD_F(0x04538c86) /* 0.270397687 */, 19 }, + /* 7307 */ { MAD_F(0x0453c045) /* 0.270447036 */, 19 }, + /* 7308 */ { MAD_F(0x0453f405) /* 0.270496386 */, 19 }, + /* 7309 */ { MAD_F(0x045427c5) /* 0.270545739 */, 19 }, + /* 7310 */ { MAD_F(0x04545b85) /* 0.270595094 */, 19 }, + /* 7311 */ { MAD_F(0x04548f46) /* 0.270644451 */, 19 }, + + /* 7312 */ { MAD_F(0x0454c308) /* 0.270693811 */, 19 }, + /* 7313 */ { MAD_F(0x0454f6cb) /* 0.270743173 */, 19 }, + /* 7314 */ { MAD_F(0x04552a8e) /* 0.270792537 */, 19 }, + /* 7315 */ { MAD_F(0x04555e51) /* 0.270841903 */, 19 }, + /* 7316 */ { MAD_F(0x04559216) /* 0.270891271 */, 19 }, + /* 7317 */ { MAD_F(0x0455c5db) /* 0.270940642 */, 19 }, + /* 7318 */ { MAD_F(0x0455f9a0) /* 0.270990015 */, 19 }, + /* 7319 */ { MAD_F(0x04562d66) /* 0.271039390 */, 19 }, + /* 7320 */ { MAD_F(0x0456612d) /* 0.271088768 */, 19 }, + /* 7321 */ { MAD_F(0x045694f4) /* 0.271138148 */, 19 }, + /* 7322 */ { MAD_F(0x0456c8bc) /* 0.271187530 */, 19 }, + /* 7323 */ { MAD_F(0x0456fc84) /* 0.271236914 */, 19 }, + /* 7324 */ { MAD_F(0x0457304e) /* 0.271286301 */, 19 }, + /* 7325 */ { MAD_F(0x04576417) /* 0.271335689 */, 19 }, + /* 7326 */ { MAD_F(0x045797e2) /* 0.271385080 */, 19 }, + /* 7327 */ { MAD_F(0x0457cbac) /* 0.271434474 */, 19 }, + + /* 7328 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 19 }, + /* 7329 */ { MAD_F(0x04583344) /* 0.271533267 */, 19 }, + /* 7330 */ { MAD_F(0x04586711) /* 0.271582667 */, 19 }, + /* 7331 */ { MAD_F(0x04589ade) /* 0.271632069 */, 19 }, + /* 7332 */ { MAD_F(0x0458ceac) /* 0.271681474 */, 19 }, + /* 7333 */ { MAD_F(0x0459027b) /* 0.271730880 */, 19 }, + /* 7334 */ { MAD_F(0x0459364a) /* 0.271780289 */, 19 }, + /* 7335 */ { MAD_F(0x04596a19) /* 0.271829701 */, 19 }, + /* 7336 */ { MAD_F(0x04599dea) /* 0.271879114 */, 19 }, + /* 7337 */ { MAD_F(0x0459d1bb) /* 0.271928530 */, 19 }, + /* 7338 */ { MAD_F(0x045a058c) /* 0.271977948 */, 19 }, + /* 7339 */ { MAD_F(0x045a395e) /* 0.272027368 */, 19 }, + /* 7340 */ { MAD_F(0x045a6d31) /* 0.272076790 */, 19 }, + /* 7341 */ { MAD_F(0x045aa104) /* 0.272126215 */, 19 }, + /* 7342 */ { MAD_F(0x045ad4d8) /* 0.272175642 */, 19 }, + /* 7343 */ { MAD_F(0x045b08ad) /* 0.272225071 */, 19 }, + + /* 7344 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 19 }, + /* 7345 */ { MAD_F(0x045b7058) /* 0.272323936 */, 19 }, + /* 7346 */ { MAD_F(0x045ba42e) /* 0.272373372 */, 19 }, + /* 7347 */ { MAD_F(0x045bd805) /* 0.272422810 */, 19 }, + /* 7348 */ { MAD_F(0x045c0bdd) /* 0.272472251 */, 19 }, + /* 7349 */ { MAD_F(0x045c3fb5) /* 0.272521693 */, 19 }, + /* 7350 */ { MAD_F(0x045c738e) /* 0.272571138 */, 19 }, + /* 7351 */ { MAD_F(0x045ca767) /* 0.272620585 */, 19 }, + /* 7352 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 19 }, + /* 7353 */ { MAD_F(0x045d0f1b) /* 0.272719486 */, 19 }, + /* 7354 */ { MAD_F(0x045d42f7) /* 0.272768940 */, 19 }, + /* 7355 */ { MAD_F(0x045d76d2) /* 0.272818396 */, 19 }, + /* 7356 */ { MAD_F(0x045daaaf) /* 0.272867855 */, 19 }, + /* 7357 */ { MAD_F(0x045dde8c) /* 0.272917315 */, 19 }, + /* 7358 */ { MAD_F(0x045e1269) /* 0.272966778 */, 19 }, + /* 7359 */ { MAD_F(0x045e4647) /* 0.273016243 */, 19 }, + + /* 7360 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 19 }, + /* 7361 */ { MAD_F(0x045eae06) /* 0.273115180 */, 19 }, + /* 7362 */ { MAD_F(0x045ee1e6) /* 0.273164652 */, 19 }, + /* 7363 */ { MAD_F(0x045f15c6) /* 0.273214126 */, 19 }, + /* 7364 */ { MAD_F(0x045f49a7) /* 0.273263602 */, 19 }, + /* 7365 */ { MAD_F(0x045f7d89) /* 0.273313081 */, 19 }, + /* 7366 */ { MAD_F(0x045fb16c) /* 0.273362561 */, 19 }, + /* 7367 */ { MAD_F(0x045fe54f) /* 0.273412044 */, 19 }, + /* 7368 */ { MAD_F(0x04601932) /* 0.273461530 */, 19 }, + /* 7369 */ { MAD_F(0x04604d16) /* 0.273511017 */, 19 }, + /* 7370 */ { MAD_F(0x046080fb) /* 0.273560507 */, 19 }, + /* 7371 */ { MAD_F(0x0460b4e1) /* 0.273609999 */, 19 }, + /* 7372 */ { MAD_F(0x0460e8c7) /* 0.273659493 */, 19 }, + /* 7373 */ { MAD_F(0x04611cad) /* 0.273708989 */, 19 }, + /* 7374 */ { MAD_F(0x04615094) /* 0.273758488 */, 19 }, + /* 7375 */ { MAD_F(0x0461847c) /* 0.273807989 */, 19 }, + + /* 7376 */ { MAD_F(0x0461b864) /* 0.273857492 */, 19 }, + /* 7377 */ { MAD_F(0x0461ec4d) /* 0.273906997 */, 19 }, + /* 7378 */ { MAD_F(0x04622037) /* 0.273956505 */, 19 }, + /* 7379 */ { MAD_F(0x04625421) /* 0.274006015 */, 19 }, + /* 7380 */ { MAD_F(0x0462880c) /* 0.274055527 */, 19 }, + /* 7381 */ { MAD_F(0x0462bbf7) /* 0.274105041 */, 19 }, + /* 7382 */ { MAD_F(0x0462efe3) /* 0.274154558 */, 19 }, + /* 7383 */ { MAD_F(0x046323d0) /* 0.274204076 */, 19 }, + /* 7384 */ { MAD_F(0x046357bd) /* 0.274253597 */, 19 }, + /* 7385 */ { MAD_F(0x04638bab) /* 0.274303121 */, 19 }, + /* 7386 */ { MAD_F(0x0463bf99) /* 0.274352646 */, 19 }, + /* 7387 */ { MAD_F(0x0463f388) /* 0.274402174 */, 19 }, + /* 7388 */ { MAD_F(0x04642778) /* 0.274451704 */, 19 }, + /* 7389 */ { MAD_F(0x04645b68) /* 0.274501236 */, 19 }, + /* 7390 */ { MAD_F(0x04648f59) /* 0.274550771 */, 19 }, + /* 7391 */ { MAD_F(0x0464c34a) /* 0.274600307 */, 19 }, + + /* 7392 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 19 }, + /* 7393 */ { MAD_F(0x04652b2f) /* 0.274699387 */, 19 }, + /* 7394 */ { MAD_F(0x04655f22) /* 0.274748931 */, 19 }, + /* 7395 */ { MAD_F(0x04659316) /* 0.274798476 */, 19 }, + /* 7396 */ { MAD_F(0x0465c70a) /* 0.274848024 */, 19 }, + /* 7397 */ { MAD_F(0x0465faff) /* 0.274897574 */, 19 }, + /* 7398 */ { MAD_F(0x04662ef5) /* 0.274947126 */, 19 }, + /* 7399 */ { MAD_F(0x046662eb) /* 0.274996681 */, 19 }, + /* 7400 */ { MAD_F(0x046696e2) /* 0.275046238 */, 19 }, + /* 7401 */ { MAD_F(0x0466cad9) /* 0.275095797 */, 19 }, + /* 7402 */ { MAD_F(0x0466fed1) /* 0.275145358 */, 19 }, + /* 7403 */ { MAD_F(0x046732ca) /* 0.275194921 */, 19 }, + /* 7404 */ { MAD_F(0x046766c3) /* 0.275244487 */, 19 }, + /* 7405 */ { MAD_F(0x04679abd) /* 0.275294055 */, 19 }, + /* 7406 */ { MAD_F(0x0467ceb7) /* 0.275343625 */, 19 }, + /* 7407 */ { MAD_F(0x046802b2) /* 0.275393198 */, 19 }, + + /* 7408 */ { MAD_F(0x046836ae) /* 0.275442772 */, 19 }, + /* 7409 */ { MAD_F(0x04686aaa) /* 0.275492349 */, 19 }, + /* 7410 */ { MAD_F(0x04689ea7) /* 0.275541928 */, 19 }, + /* 7411 */ { MAD_F(0x0468d2a4) /* 0.275591509 */, 19 }, + /* 7412 */ { MAD_F(0x046906a2) /* 0.275641093 */, 19 }, + /* 7413 */ { MAD_F(0x04693aa1) /* 0.275690679 */, 19 }, + /* 7414 */ { MAD_F(0x04696ea0) /* 0.275740267 */, 19 }, + /* 7415 */ { MAD_F(0x0469a2a0) /* 0.275789857 */, 19 }, + /* 7416 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 19 }, + /* 7417 */ { MAD_F(0x046a0aa1) /* 0.275889044 */, 19 }, + /* 7418 */ { MAD_F(0x046a3ea3) /* 0.275938641 */, 19 }, + /* 7419 */ { MAD_F(0x046a72a5) /* 0.275988240 */, 19 }, + /* 7420 */ { MAD_F(0x046aa6a8) /* 0.276037842 */, 19 }, + /* 7421 */ { MAD_F(0x046adaab) /* 0.276087445 */, 19 }, + /* 7422 */ { MAD_F(0x046b0eaf) /* 0.276137051 */, 19 }, + /* 7423 */ { MAD_F(0x046b42b3) /* 0.276186659 */, 19 }, + + /* 7424 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 19 }, + /* 7425 */ { MAD_F(0x046baabe) /* 0.276285882 */, 19 }, + /* 7426 */ { MAD_F(0x046bdec5) /* 0.276335497 */, 19 }, + /* 7427 */ { MAD_F(0x046c12cc) /* 0.276385113 */, 19 }, + /* 7428 */ { MAD_F(0x046c46d3) /* 0.276434733 */, 19 }, + /* 7429 */ { MAD_F(0x046c7adb) /* 0.276484354 */, 19 }, + /* 7430 */ { MAD_F(0x046caee4) /* 0.276533978 */, 19 }, + /* 7431 */ { MAD_F(0x046ce2ee) /* 0.276583604 */, 19 }, + /* 7432 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 19 }, + /* 7433 */ { MAD_F(0x046d4b02) /* 0.276682862 */, 19 }, + /* 7434 */ { MAD_F(0x046d7f0d) /* 0.276732495 */, 19 }, + /* 7435 */ { MAD_F(0x046db319) /* 0.276782129 */, 19 }, + /* 7436 */ { MAD_F(0x046de725) /* 0.276831766 */, 19 }, + /* 7437 */ { MAD_F(0x046e1b32) /* 0.276881406 */, 19 }, + /* 7438 */ { MAD_F(0x046e4f40) /* 0.276931047 */, 19 }, + /* 7439 */ { MAD_F(0x046e834e) /* 0.276980691 */, 19 }, + + /* 7440 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 19 }, + /* 7441 */ { MAD_F(0x046eeb6c) /* 0.277079985 */, 19 }, + /* 7442 */ { MAD_F(0x046f1f7c) /* 0.277129635 */, 19 }, + /* 7443 */ { MAD_F(0x046f538c) /* 0.277179288 */, 19 }, + /* 7444 */ { MAD_F(0x046f879d) /* 0.277228942 */, 19 }, + /* 7445 */ { MAD_F(0x046fbbaf) /* 0.277278600 */, 19 }, + /* 7446 */ { MAD_F(0x046fefc1) /* 0.277328259 */, 19 }, + /* 7447 */ { MAD_F(0x047023d4) /* 0.277377920 */, 19 }, + /* 7448 */ { MAD_F(0x047057e8) /* 0.277427584 */, 19 }, + /* 7449 */ { MAD_F(0x04708bfc) /* 0.277477250 */, 19 }, + /* 7450 */ { MAD_F(0x0470c011) /* 0.277526918 */, 19 }, + /* 7451 */ { MAD_F(0x0470f426) /* 0.277576588 */, 19 }, + /* 7452 */ { MAD_F(0x0471283c) /* 0.277626261 */, 19 }, + /* 7453 */ { MAD_F(0x04715c52) /* 0.277675936 */, 19 }, + /* 7454 */ { MAD_F(0x04719069) /* 0.277725613 */, 19 }, + /* 7455 */ { MAD_F(0x0471c481) /* 0.277775292 */, 19 }, + + /* 7456 */ { MAD_F(0x0471f899) /* 0.277824973 */, 19 }, + /* 7457 */ { MAD_F(0x04722cb2) /* 0.277874657 */, 19 }, + /* 7458 */ { MAD_F(0x047260cc) /* 0.277924343 */, 19 }, + /* 7459 */ { MAD_F(0x047294e6) /* 0.277974031 */, 19 }, + /* 7460 */ { MAD_F(0x0472c900) /* 0.278023722 */, 19 }, + /* 7461 */ { MAD_F(0x0472fd1b) /* 0.278073414 */, 19 }, + /* 7462 */ { MAD_F(0x04733137) /* 0.278123109 */, 19 }, + /* 7463 */ { MAD_F(0x04736554) /* 0.278172806 */, 19 }, + /* 7464 */ { MAD_F(0x04739971) /* 0.278222505 */, 19 }, + /* 7465 */ { MAD_F(0x0473cd8e) /* 0.278272207 */, 19 }, + /* 7466 */ { MAD_F(0x047401ad) /* 0.278321910 */, 19 }, + /* 7467 */ { MAD_F(0x047435cb) /* 0.278371616 */, 19 }, + /* 7468 */ { MAD_F(0x047469eb) /* 0.278421324 */, 19 }, + /* 7469 */ { MAD_F(0x04749e0b) /* 0.278471035 */, 19 }, + /* 7470 */ { MAD_F(0x0474d22c) /* 0.278520747 */, 19 }, + /* 7471 */ { MAD_F(0x0475064d) /* 0.278570462 */, 19 }, + + /* 7472 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 19 }, + /* 7473 */ { MAD_F(0x04756e91) /* 0.278669898 */, 19 }, + /* 7474 */ { MAD_F(0x0475a2b4) /* 0.278719619 */, 19 }, + /* 7475 */ { MAD_F(0x0475d6d7) /* 0.278769343 */, 19 }, + /* 7476 */ { MAD_F(0x04760afc) /* 0.278819069 */, 19 }, + /* 7477 */ { MAD_F(0x04763f20) /* 0.278868797 */, 19 }, + /* 7478 */ { MAD_F(0x04767346) /* 0.278918527 */, 19 }, + /* 7479 */ { MAD_F(0x0476a76c) /* 0.278968260 */, 19 }, + /* 7480 */ { MAD_F(0x0476db92) /* 0.279017995 */, 19 }, + /* 7481 */ { MAD_F(0x04770fba) /* 0.279067731 */, 19 }, + /* 7482 */ { MAD_F(0x047743e1) /* 0.279117471 */, 19 }, + /* 7483 */ { MAD_F(0x0477780a) /* 0.279167212 */, 19 }, + /* 7484 */ { MAD_F(0x0477ac33) /* 0.279216956 */, 19 }, + /* 7485 */ { MAD_F(0x0477e05c) /* 0.279266701 */, 19 }, + /* 7486 */ { MAD_F(0x04781486) /* 0.279316449 */, 19 }, + /* 7487 */ { MAD_F(0x047848b1) /* 0.279366200 */, 19 }, + + /* 7488 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 19 }, + /* 7489 */ { MAD_F(0x0478b108) /* 0.279465707 */, 19 }, + /* 7490 */ { MAD_F(0x0478e535) /* 0.279515464 */, 19 }, + /* 7491 */ { MAD_F(0x04791962) /* 0.279565223 */, 19 }, + /* 7492 */ { MAD_F(0x04794d8f) /* 0.279614984 */, 19 }, + /* 7493 */ { MAD_F(0x047981be) /* 0.279664748 */, 19 }, + /* 7494 */ { MAD_F(0x0479b5ed) /* 0.279714513 */, 19 }, + /* 7495 */ { MAD_F(0x0479ea1c) /* 0.279764281 */, 19 }, + /* 7496 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 19 }, + /* 7497 */ { MAD_F(0x047a527d) /* 0.279863824 */, 19 }, + /* 7498 */ { MAD_F(0x047a86ae) /* 0.279913598 */, 19 }, + /* 7499 */ { MAD_F(0x047abae0) /* 0.279963375 */, 19 }, + /* 7500 */ { MAD_F(0x047aef12) /* 0.280013154 */, 19 }, + /* 7501 */ { MAD_F(0x047b2346) /* 0.280062935 */, 19 }, + /* 7502 */ { MAD_F(0x047b5779) /* 0.280112719 */, 19 }, + /* 7503 */ { MAD_F(0x047b8bad) /* 0.280162504 */, 19 }, + + /* 7504 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 19 }, + /* 7505 */ { MAD_F(0x047bf418) /* 0.280262082 */, 19 }, + /* 7506 */ { MAD_F(0x047c284e) /* 0.280311875 */, 19 }, + /* 7507 */ { MAD_F(0x047c5c84) /* 0.280361669 */, 19 }, + /* 7508 */ { MAD_F(0x047c90bb) /* 0.280411466 */, 19 }, + /* 7509 */ { MAD_F(0x047cc4f3) /* 0.280461265 */, 19 }, + /* 7510 */ { MAD_F(0x047cf92c) /* 0.280511066 */, 19 }, + /* 7511 */ { MAD_F(0x047d2d65) /* 0.280560869 */, 19 }, + /* 7512 */ { MAD_F(0x047d619e) /* 0.280610675 */, 19 }, + /* 7513 */ { MAD_F(0x047d95d8) /* 0.280660483 */, 19 }, + /* 7514 */ { MAD_F(0x047dca13) /* 0.280710292 */, 19 }, + /* 7515 */ { MAD_F(0x047dfe4e) /* 0.280760105 */, 19 }, + /* 7516 */ { MAD_F(0x047e328a) /* 0.280809919 */, 19 }, + /* 7517 */ { MAD_F(0x047e66c7) /* 0.280859736 */, 19 }, + /* 7518 */ { MAD_F(0x047e9b04) /* 0.280909554 */, 19 }, + /* 7519 */ { MAD_F(0x047ecf42) /* 0.280959375 */, 19 }, + + /* 7520 */ { MAD_F(0x047f0380) /* 0.281009199 */, 19 }, + /* 7521 */ { MAD_F(0x047f37bf) /* 0.281059024 */, 19 }, + /* 7522 */ { MAD_F(0x047f6bff) /* 0.281108852 */, 19 }, + /* 7523 */ { MAD_F(0x047fa03f) /* 0.281158682 */, 19 }, + /* 7524 */ { MAD_F(0x047fd47f) /* 0.281208514 */, 19 }, + /* 7525 */ { MAD_F(0x048008c1) /* 0.281258348 */, 19 }, + /* 7526 */ { MAD_F(0x04803d02) /* 0.281308184 */, 19 }, + /* 7527 */ { MAD_F(0x04807145) /* 0.281358023 */, 19 }, + /* 7528 */ { MAD_F(0x0480a588) /* 0.281407864 */, 19 }, + /* 7529 */ { MAD_F(0x0480d9cc) /* 0.281457707 */, 19 }, + /* 7530 */ { MAD_F(0x04810e10) /* 0.281507552 */, 19 }, + /* 7531 */ { MAD_F(0x04814255) /* 0.281557400 */, 19 }, + /* 7532 */ { MAD_F(0x0481769a) /* 0.281607250 */, 19 }, + /* 7533 */ { MAD_F(0x0481aae0) /* 0.281657101 */, 19 }, + /* 7534 */ { MAD_F(0x0481df27) /* 0.281706956 */, 19 }, + /* 7535 */ { MAD_F(0x0482136e) /* 0.281756812 */, 19 }, + + /* 7536 */ { MAD_F(0x048247b6) /* 0.281806670 */, 19 }, + /* 7537 */ { MAD_F(0x04827bfe) /* 0.281856531 */, 19 }, + /* 7538 */ { MAD_F(0x0482b047) /* 0.281906394 */, 19 }, + /* 7539 */ { MAD_F(0x0482e491) /* 0.281956259 */, 19 }, + /* 7540 */ { MAD_F(0x048318db) /* 0.282006127 */, 19 }, + /* 7541 */ { MAD_F(0x04834d26) /* 0.282055996 */, 19 }, + /* 7542 */ { MAD_F(0x04838171) /* 0.282105868 */, 19 }, + /* 7543 */ { MAD_F(0x0483b5bd) /* 0.282155742 */, 19 }, + /* 7544 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 19 }, + /* 7545 */ { MAD_F(0x04841e57) /* 0.282255496 */, 19 }, + /* 7546 */ { MAD_F(0x048452a4) /* 0.282305377 */, 19 }, + /* 7547 */ { MAD_F(0x048486f3) /* 0.282355260 */, 19 }, + /* 7548 */ { MAD_F(0x0484bb42) /* 0.282405145 */, 19 }, + /* 7549 */ { MAD_F(0x0484ef91) /* 0.282455032 */, 19 }, + /* 7550 */ { MAD_F(0x048523e1) /* 0.282504921 */, 19 }, + /* 7551 */ { MAD_F(0x04855832) /* 0.282554813 */, 19 }, + + /* 7552 */ { MAD_F(0x04858c83) /* 0.282604707 */, 19 }, + /* 7553 */ { MAD_F(0x0485c0d5) /* 0.282654603 */, 19 }, + /* 7554 */ { MAD_F(0x0485f527) /* 0.282704501 */, 19 }, + /* 7555 */ { MAD_F(0x0486297a) /* 0.282754401 */, 19 }, + /* 7556 */ { MAD_F(0x04865dce) /* 0.282804304 */, 19 }, + /* 7557 */ { MAD_F(0x04869222) /* 0.282854209 */, 19 }, + /* 7558 */ { MAD_F(0x0486c677) /* 0.282904116 */, 19 }, + /* 7559 */ { MAD_F(0x0486facc) /* 0.282954025 */, 19 }, + /* 7560 */ { MAD_F(0x04872f22) /* 0.283003936 */, 19 }, + /* 7561 */ { MAD_F(0x04876379) /* 0.283053850 */, 19 }, + /* 7562 */ { MAD_F(0x048797d0) /* 0.283103766 */, 19 }, + /* 7563 */ { MAD_F(0x0487cc28) /* 0.283153684 */, 19 }, + /* 7564 */ { MAD_F(0x04880080) /* 0.283203604 */, 19 }, + /* 7565 */ { MAD_F(0x048834d9) /* 0.283253527 */, 19 }, + /* 7566 */ { MAD_F(0x04886933) /* 0.283303451 */, 19 }, + /* 7567 */ { MAD_F(0x04889d8d) /* 0.283353378 */, 19 }, + + /* 7568 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 19 }, + /* 7569 */ { MAD_F(0x04890643) /* 0.283453238 */, 19 }, + /* 7570 */ { MAD_F(0x04893a9f) /* 0.283503172 */, 19 }, + /* 7571 */ { MAD_F(0x04896efb) /* 0.283553107 */, 19 }, + /* 7572 */ { MAD_F(0x0489a358) /* 0.283603045 */, 19 }, + /* 7573 */ { MAD_F(0x0489d7b6) /* 0.283652985 */, 19 }, + /* 7574 */ { MAD_F(0x048a0c14) /* 0.283702927 */, 19 }, + /* 7575 */ { MAD_F(0x048a4073) /* 0.283752872 */, 19 }, + /* 7576 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 19 }, + /* 7577 */ { MAD_F(0x048aa933) /* 0.283852767 */, 19 }, + /* 7578 */ { MAD_F(0x048add93) /* 0.283902718 */, 19 }, + /* 7579 */ { MAD_F(0x048b11f5) /* 0.283952671 */, 19 }, + /* 7580 */ { MAD_F(0x048b4656) /* 0.284002627 */, 19 }, + /* 7581 */ { MAD_F(0x048b7ab9) /* 0.284052584 */, 19 }, + /* 7582 */ { MAD_F(0x048baf1c) /* 0.284102544 */, 19 }, + /* 7583 */ { MAD_F(0x048be37f) /* 0.284152506 */, 19 }, + + /* 7584 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 19 }, + /* 7585 */ { MAD_F(0x048c4c48) /* 0.284252436 */, 19 }, + /* 7586 */ { MAD_F(0x048c80ad) /* 0.284302405 */, 19 }, + /* 7587 */ { MAD_F(0x048cb513) /* 0.284352376 */, 19 }, + /* 7588 */ { MAD_F(0x048ce97a) /* 0.284402349 */, 19 }, + /* 7589 */ { MAD_F(0x048d1de1) /* 0.284452324 */, 19 }, + /* 7590 */ { MAD_F(0x048d5249) /* 0.284502301 */, 19 }, + /* 7591 */ { MAD_F(0x048d86b1) /* 0.284552281 */, 19 }, + /* 7592 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 19 }, + /* 7593 */ { MAD_F(0x048def83) /* 0.284652246 */, 19 }, + /* 7594 */ { MAD_F(0x048e23ed) /* 0.284702233 */, 19 }, + /* 7595 */ { MAD_F(0x048e5858) /* 0.284752221 */, 19 }, + /* 7596 */ { MAD_F(0x048e8cc3) /* 0.284802211 */, 19 }, + /* 7597 */ { MAD_F(0x048ec12f) /* 0.284852204 */, 19 }, + /* 7598 */ { MAD_F(0x048ef59b) /* 0.284902199 */, 19 }, + /* 7599 */ { MAD_F(0x048f2a08) /* 0.284952196 */, 19 }, + + /* 7600 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 19 }, + /* 7601 */ { MAD_F(0x048f92e4) /* 0.285052197 */, 19 }, + /* 7602 */ { MAD_F(0x048fc753) /* 0.285102201 */, 19 }, + /* 7603 */ { MAD_F(0x048ffbc2) /* 0.285152206 */, 19 }, + /* 7604 */ { MAD_F(0x04903032) /* 0.285202214 */, 19 }, + /* 7605 */ { MAD_F(0x049064a3) /* 0.285252225 */, 19 }, + /* 7606 */ { MAD_F(0x04909914) /* 0.285302237 */, 19 }, + /* 7607 */ { MAD_F(0x0490cd86) /* 0.285352252 */, 19 }, + /* 7608 */ { MAD_F(0x049101f8) /* 0.285402269 */, 19 }, + /* 7609 */ { MAD_F(0x0491366b) /* 0.285452288 */, 19 }, + /* 7610 */ { MAD_F(0x04916ade) /* 0.285502309 */, 19 }, + /* 7611 */ { MAD_F(0x04919f52) /* 0.285552332 */, 19 }, + /* 7612 */ { MAD_F(0x0491d3c7) /* 0.285602358 */, 19 }, + /* 7613 */ { MAD_F(0x0492083c) /* 0.285652386 */, 19 }, + /* 7614 */ { MAD_F(0x04923cb2) /* 0.285702416 */, 19 }, + /* 7615 */ { MAD_F(0x04927128) /* 0.285752448 */, 19 }, + + /* 7616 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 19 }, + /* 7617 */ { MAD_F(0x0492da17) /* 0.285852519 */, 19 }, + /* 7618 */ { MAD_F(0x04930e8f) /* 0.285902557 */, 19 }, + /* 7619 */ { MAD_F(0x04934308) /* 0.285952598 */, 19 }, + /* 7620 */ { MAD_F(0x04937781) /* 0.286002641 */, 19 }, + /* 7621 */ { MAD_F(0x0493abfb) /* 0.286052687 */, 19 }, + /* 7622 */ { MAD_F(0x0493e076) /* 0.286102734 */, 19 }, + /* 7623 */ { MAD_F(0x049414f1) /* 0.286152784 */, 19 }, + /* 7624 */ { MAD_F(0x0494496c) /* 0.286202836 */, 19 }, + /* 7625 */ { MAD_F(0x04947de9) /* 0.286252890 */, 19 }, + /* 7626 */ { MAD_F(0x0494b266) /* 0.286302946 */, 19 }, + /* 7627 */ { MAD_F(0x0494e6e3) /* 0.286353005 */, 19 }, + /* 7628 */ { MAD_F(0x04951b61) /* 0.286403065 */, 19 }, + /* 7629 */ { MAD_F(0x04954fe0) /* 0.286453128 */, 19 }, + /* 7630 */ { MAD_F(0x0495845f) /* 0.286503193 */, 19 }, + /* 7631 */ { MAD_F(0x0495b8df) /* 0.286553260 */, 19 }, + + /* 7632 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 19 }, + /* 7633 */ { MAD_F(0x049621e0) /* 0.286653401 */, 19 }, + /* 7634 */ { MAD_F(0x04965662) /* 0.286703475 */, 19 }, + /* 7635 */ { MAD_F(0x04968ae4) /* 0.286753551 */, 19 }, + /* 7636 */ { MAD_F(0x0496bf67) /* 0.286803629 */, 19 }, + /* 7637 */ { MAD_F(0x0496f3ea) /* 0.286853709 */, 19 }, + /* 7638 */ { MAD_F(0x0497286e) /* 0.286903792 */, 19 }, + /* 7639 */ { MAD_F(0x04975cf2) /* 0.286953876 */, 19 }, + /* 7640 */ { MAD_F(0x04979177) /* 0.287003963 */, 19 }, + /* 7641 */ { MAD_F(0x0497c5fd) /* 0.287054052 */, 19 }, + /* 7642 */ { MAD_F(0x0497fa83) /* 0.287104143 */, 19 }, + /* 7643 */ { MAD_F(0x04982f0a) /* 0.287154237 */, 19 }, + /* 7644 */ { MAD_F(0x04986392) /* 0.287204332 */, 19 }, + /* 7645 */ { MAD_F(0x0498981a) /* 0.287254430 */, 19 }, + /* 7646 */ { MAD_F(0x0498cca2) /* 0.287304530 */, 19 }, + /* 7647 */ { MAD_F(0x0499012c) /* 0.287354632 */, 19 }, + + /* 7648 */ { MAD_F(0x049935b5) /* 0.287404737 */, 19 }, + /* 7649 */ { MAD_F(0x04996a40) /* 0.287454843 */, 19 }, + /* 7650 */ { MAD_F(0x04999ecb) /* 0.287504952 */, 19 }, + /* 7651 */ { MAD_F(0x0499d356) /* 0.287555063 */, 19 }, + /* 7652 */ { MAD_F(0x049a07e2) /* 0.287605176 */, 19 }, + /* 7653 */ { MAD_F(0x049a3c6f) /* 0.287655291 */, 19 }, + /* 7654 */ { MAD_F(0x049a70fc) /* 0.287705409 */, 19 }, + /* 7655 */ { MAD_F(0x049aa58a) /* 0.287755528 */, 19 }, + /* 7656 */ { MAD_F(0x049ada19) /* 0.287805650 */, 19 }, + /* 7657 */ { MAD_F(0x049b0ea8) /* 0.287855774 */, 19 }, + /* 7658 */ { MAD_F(0x049b4337) /* 0.287905900 */, 19 }, + /* 7659 */ { MAD_F(0x049b77c8) /* 0.287956028 */, 19 }, + /* 7660 */ { MAD_F(0x049bac58) /* 0.288006159 */, 19 }, + /* 7661 */ { MAD_F(0x049be0ea) /* 0.288056292 */, 19 }, + /* 7662 */ { MAD_F(0x049c157c) /* 0.288106427 */, 19 }, + /* 7663 */ { MAD_F(0x049c4a0e) /* 0.288156564 */, 19 }, + + /* 7664 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 19 }, + /* 7665 */ { MAD_F(0x049cb335) /* 0.288256844 */, 19 }, + /* 7666 */ { MAD_F(0x049ce7ca) /* 0.288306988 */, 19 }, + /* 7667 */ { MAD_F(0x049d1c5e) /* 0.288357134 */, 19 }, + /* 7668 */ { MAD_F(0x049d50f4) /* 0.288407282 */, 19 }, + /* 7669 */ { MAD_F(0x049d858a) /* 0.288457432 */, 19 }, + /* 7670 */ { MAD_F(0x049dba21) /* 0.288507584 */, 19 }, + /* 7671 */ { MAD_F(0x049deeb8) /* 0.288557739 */, 19 }, + /* 7672 */ { MAD_F(0x049e2350) /* 0.288607895 */, 19 }, + /* 7673 */ { MAD_F(0x049e57e8) /* 0.288658054 */, 19 }, + /* 7674 */ { MAD_F(0x049e8c81) /* 0.288708215 */, 19 }, + /* 7675 */ { MAD_F(0x049ec11b) /* 0.288758379 */, 19 }, + /* 7676 */ { MAD_F(0x049ef5b5) /* 0.288808544 */, 19 }, + /* 7677 */ { MAD_F(0x049f2a50) /* 0.288858712 */, 19 }, + /* 7678 */ { MAD_F(0x049f5eeb) /* 0.288908881 */, 19 }, + /* 7679 */ { MAD_F(0x049f9387) /* 0.288959053 */, 19 }, + + /* 7680 */ { MAD_F(0x049fc824) /* 0.289009227 */, 19 }, + /* 7681 */ { MAD_F(0x049ffcc1) /* 0.289059404 */, 19 }, + /* 7682 */ { MAD_F(0x04a0315e) /* 0.289109582 */, 19 }, + /* 7683 */ { MAD_F(0x04a065fd) /* 0.289159763 */, 19 }, + /* 7684 */ { MAD_F(0x04a09a9b) /* 0.289209946 */, 19 }, + /* 7685 */ { MAD_F(0x04a0cf3b) /* 0.289260131 */, 19 }, + /* 7686 */ { MAD_F(0x04a103db) /* 0.289310318 */, 19 }, + /* 7687 */ { MAD_F(0x04a1387b) /* 0.289360507 */, 19 }, + /* 7688 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 19 }, + /* 7689 */ { MAD_F(0x04a1a1be) /* 0.289460893 */, 19 }, + /* 7690 */ { MAD_F(0x04a1d661) /* 0.289511088 */, 19 }, + /* 7691 */ { MAD_F(0x04a20b04) /* 0.289561287 */, 19 }, + /* 7692 */ { MAD_F(0x04a23fa7) /* 0.289611487 */, 19 }, + /* 7693 */ { MAD_F(0x04a2744b) /* 0.289661689 */, 19 }, + /* 7694 */ { MAD_F(0x04a2a8f0) /* 0.289711894 */, 19 }, + /* 7695 */ { MAD_F(0x04a2dd95) /* 0.289762101 */, 19 }, + + /* 7696 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 19 }, + /* 7697 */ { MAD_F(0x04a346e2) /* 0.289862521 */, 19 }, + /* 7698 */ { MAD_F(0x04a37b89) /* 0.289912734 */, 19 }, + /* 7699 */ { MAD_F(0x04a3b030) /* 0.289962949 */, 19 }, + /* 7700 */ { MAD_F(0x04a3e4d8) /* 0.290013167 */, 19 }, + /* 7701 */ { MAD_F(0x04a41981) /* 0.290063387 */, 19 }, + /* 7702 */ { MAD_F(0x04a44e2b) /* 0.290113609 */, 19 }, + /* 7703 */ { MAD_F(0x04a482d5) /* 0.290163833 */, 19 }, + /* 7704 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 19 }, + /* 7705 */ { MAD_F(0x04a4ec2a) /* 0.290264288 */, 19 }, + /* 7706 */ { MAD_F(0x04a520d6) /* 0.290314519 */, 19 }, + /* 7707 */ { MAD_F(0x04a55582) /* 0.290364751 */, 19 }, + /* 7708 */ { MAD_F(0x04a58a2f) /* 0.290414986 */, 19 }, + /* 7709 */ { MAD_F(0x04a5bedd) /* 0.290465224 */, 19 }, + /* 7710 */ { MAD_F(0x04a5f38b) /* 0.290515463 */, 19 }, + /* 7711 */ { MAD_F(0x04a62839) /* 0.290565705 */, 19 }, + + /* 7712 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 19 }, + /* 7713 */ { MAD_F(0x04a69198) /* 0.290666194 */, 19 }, + /* 7714 */ { MAD_F(0x04a6c648) /* 0.290716442 */, 19 }, + /* 7715 */ { MAD_F(0x04a6faf9) /* 0.290766692 */, 19 }, + /* 7716 */ { MAD_F(0x04a72fab) /* 0.290816945 */, 19 }, + /* 7717 */ { MAD_F(0x04a7645d) /* 0.290867199 */, 19 }, + /* 7718 */ { MAD_F(0x04a79910) /* 0.290917456 */, 19 }, + /* 7719 */ { MAD_F(0x04a7cdc3) /* 0.290967715 */, 19 }, + /* 7720 */ { MAD_F(0x04a80277) /* 0.291017976 */, 19 }, + /* 7721 */ { MAD_F(0x04a8372b) /* 0.291068239 */, 19 }, + /* 7722 */ { MAD_F(0x04a86be0) /* 0.291118505 */, 19 }, + /* 7723 */ { MAD_F(0x04a8a096) /* 0.291168772 */, 19 }, + /* 7724 */ { MAD_F(0x04a8d54c) /* 0.291219042 */, 19 }, + /* 7725 */ { MAD_F(0x04a90a03) /* 0.291269314 */, 19 }, + /* 7726 */ { MAD_F(0x04a93eba) /* 0.291319588 */, 19 }, + /* 7727 */ { MAD_F(0x04a97372) /* 0.291369865 */, 19 }, + + /* 7728 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 19 }, + /* 7729 */ { MAD_F(0x04a9dce4) /* 0.291470424 */, 19 }, + /* 7730 */ { MAD_F(0x04aa119d) /* 0.291520706 */, 19 }, + /* 7731 */ { MAD_F(0x04aa4658) /* 0.291570991 */, 19 }, + /* 7732 */ { MAD_F(0x04aa7b13) /* 0.291621278 */, 19 }, + /* 7733 */ { MAD_F(0x04aaafce) /* 0.291671568 */, 19 }, + /* 7734 */ { MAD_F(0x04aae48a) /* 0.291721859 */, 19 }, + /* 7735 */ { MAD_F(0x04ab1947) /* 0.291772153 */, 19 }, + /* 7736 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 19 }, + /* 7737 */ { MAD_F(0x04ab82c2) /* 0.291872747 */, 19 }, + /* 7738 */ { MAD_F(0x04abb780) /* 0.291923047 */, 19 }, + /* 7739 */ { MAD_F(0x04abec3f) /* 0.291973349 */, 19 }, + /* 7740 */ { MAD_F(0x04ac20fe) /* 0.292023653 */, 19 }, + /* 7741 */ { MAD_F(0x04ac55be) /* 0.292073960 */, 19 }, + /* 7742 */ { MAD_F(0x04ac8a7f) /* 0.292124269 */, 19 }, + /* 7743 */ { MAD_F(0x04acbf40) /* 0.292174580 */, 19 }, + + /* 7744 */ { MAD_F(0x04acf402) /* 0.292224893 */, 19 }, + /* 7745 */ { MAD_F(0x04ad28c5) /* 0.292275208 */, 19 }, + /* 7746 */ { MAD_F(0x04ad5d88) /* 0.292325526 */, 19 }, + /* 7747 */ { MAD_F(0x04ad924b) /* 0.292375845 */, 19 }, + /* 7748 */ { MAD_F(0x04adc70f) /* 0.292426167 */, 19 }, + /* 7749 */ { MAD_F(0x04adfbd4) /* 0.292476491 */, 19 }, + /* 7750 */ { MAD_F(0x04ae3099) /* 0.292526817 */, 19 }, + /* 7751 */ { MAD_F(0x04ae655f) /* 0.292577145 */, 19 }, + /* 7752 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 19 }, + /* 7753 */ { MAD_F(0x04aeceed) /* 0.292677808 */, 19 }, + /* 7754 */ { MAD_F(0x04af03b4) /* 0.292728143 */, 19 }, + /* 7755 */ { MAD_F(0x04af387d) /* 0.292778480 */, 19 }, + /* 7756 */ { MAD_F(0x04af6d45) /* 0.292828819 */, 19 }, + /* 7757 */ { MAD_F(0x04afa20f) /* 0.292879160 */, 19 }, + /* 7758 */ { MAD_F(0x04afd6d9) /* 0.292929504 */, 19 }, + /* 7759 */ { MAD_F(0x04b00ba3) /* 0.292979849 */, 19 }, + + /* 7760 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 19 }, + /* 7761 */ { MAD_F(0x04b0753a) /* 0.293080547 */, 19 }, + /* 7762 */ { MAD_F(0x04b0aa06) /* 0.293130899 */, 19 }, + /* 7763 */ { MAD_F(0x04b0ded3) /* 0.293181253 */, 19 }, + /* 7764 */ { MAD_F(0x04b113a1) /* 0.293231610 */, 19 }, + /* 7765 */ { MAD_F(0x04b1486f) /* 0.293281968 */, 19 }, + /* 7766 */ { MAD_F(0x04b17d3d) /* 0.293332329 */, 19 }, + /* 7767 */ { MAD_F(0x04b1b20c) /* 0.293382692 */, 19 }, + /* 7768 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 19 }, + /* 7769 */ { MAD_F(0x04b21bad) /* 0.293483424 */, 19 }, + /* 7770 */ { MAD_F(0x04b2507d) /* 0.293533794 */, 19 }, + /* 7771 */ { MAD_F(0x04b2854f) /* 0.293584165 */, 19 }, + /* 7772 */ { MAD_F(0x04b2ba21) /* 0.293634539 */, 19 }, + /* 7773 */ { MAD_F(0x04b2eef4) /* 0.293684915 */, 19 }, + /* 7774 */ { MAD_F(0x04b323c7) /* 0.293735293 */, 19 }, + /* 7775 */ { MAD_F(0x04b3589b) /* 0.293785673 */, 19 }, + + /* 7776 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 19 }, + /* 7777 */ { MAD_F(0x04b3c244) /* 0.293886440 */, 19 }, + /* 7778 */ { MAD_F(0x04b3f71a) /* 0.293936826 */, 19 }, + /* 7779 */ { MAD_F(0x04b42bf0) /* 0.293987215 */, 19 }, + /* 7780 */ { MAD_F(0x04b460c7) /* 0.294037606 */, 19 }, + /* 7781 */ { MAD_F(0x04b4959e) /* 0.294087999 */, 19 }, + /* 7782 */ { MAD_F(0x04b4ca76) /* 0.294138395 */, 19 }, + /* 7783 */ { MAD_F(0x04b4ff4e) /* 0.294188792 */, 19 }, + /* 7784 */ { MAD_F(0x04b53427) /* 0.294239192 */, 19 }, + /* 7785 */ { MAD_F(0x04b56901) /* 0.294289593 */, 19 }, + /* 7786 */ { MAD_F(0x04b59ddb) /* 0.294339997 */, 19 }, + /* 7787 */ { MAD_F(0x04b5d2b6) /* 0.294390403 */, 19 }, + /* 7788 */ { MAD_F(0x04b60791) /* 0.294440812 */, 19 }, + /* 7789 */ { MAD_F(0x04b63c6d) /* 0.294491222 */, 19 }, + /* 7790 */ { MAD_F(0x04b6714a) /* 0.294541635 */, 19 }, + /* 7791 */ { MAD_F(0x04b6a627) /* 0.294592049 */, 19 }, + + /* 7792 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 19 }, + /* 7793 */ { MAD_F(0x04b70fe3) /* 0.294692885 */, 19 }, + /* 7794 */ { MAD_F(0x04b744c2) /* 0.294743306 */, 19 }, + /* 7795 */ { MAD_F(0x04b779a1) /* 0.294793730 */, 19 }, + /* 7796 */ { MAD_F(0x04b7ae81) /* 0.294844155 */, 19 }, + /* 7797 */ { MAD_F(0x04b7e362) /* 0.294894583 */, 19 }, + /* 7798 */ { MAD_F(0x04b81843) /* 0.294945013 */, 19 }, + /* 7799 */ { MAD_F(0x04b84d24) /* 0.294995445 */, 19 }, + /* 7800 */ { MAD_F(0x04b88207) /* 0.295045879 */, 19 }, + /* 7801 */ { MAD_F(0x04b8b6ea) /* 0.295096315 */, 19 }, + /* 7802 */ { MAD_F(0x04b8ebcd) /* 0.295146753 */, 19 }, + /* 7803 */ { MAD_F(0x04b920b1) /* 0.295197194 */, 19 }, + /* 7804 */ { MAD_F(0x04b95596) /* 0.295247637 */, 19 }, + /* 7805 */ { MAD_F(0x04b98a7b) /* 0.295298082 */, 19 }, + /* 7806 */ { MAD_F(0x04b9bf61) /* 0.295348529 */, 19 }, + /* 7807 */ { MAD_F(0x04b9f447) /* 0.295398978 */, 19 }, + + /* 7808 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 19 }, + /* 7809 */ { MAD_F(0x04ba5e16) /* 0.295499883 */, 19 }, + /* 7810 */ { MAD_F(0x04ba92fe) /* 0.295550338 */, 19 }, + /* 7811 */ { MAD_F(0x04bac7e6) /* 0.295600796 */, 19 }, + /* 7812 */ { MAD_F(0x04bafcd0) /* 0.295651256 */, 19 }, + /* 7813 */ { MAD_F(0x04bb31b9) /* 0.295701718 */, 19 }, + /* 7814 */ { MAD_F(0x04bb66a4) /* 0.295752183 */, 19 }, + /* 7815 */ { MAD_F(0x04bb9b8f) /* 0.295802649 */, 19 }, + /* 7816 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 19 }, + /* 7817 */ { MAD_F(0x04bc0566) /* 0.295903588 */, 19 }, + /* 7818 */ { MAD_F(0x04bc3a53) /* 0.295954061 */, 19 }, + /* 7819 */ { MAD_F(0x04bc6f40) /* 0.296004536 */, 19 }, + /* 7820 */ { MAD_F(0x04bca42e) /* 0.296055013 */, 19 }, + /* 7821 */ { MAD_F(0x04bcd91d) /* 0.296105493 */, 19 }, + /* 7822 */ { MAD_F(0x04bd0e0c) /* 0.296155974 */, 19 }, + /* 7823 */ { MAD_F(0x04bd42fb) /* 0.296206458 */, 19 }, + + /* 7824 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 19 }, + /* 7825 */ { MAD_F(0x04bdacdc) /* 0.296307432 */, 19 }, + /* 7826 */ { MAD_F(0x04bde1ce) /* 0.296357922 */, 19 }, + /* 7827 */ { MAD_F(0x04be16c0) /* 0.296408414 */, 19 }, + /* 7828 */ { MAD_F(0x04be4bb2) /* 0.296458908 */, 19 }, + /* 7829 */ { MAD_F(0x04be80a5) /* 0.296509405 */, 19 }, + /* 7830 */ { MAD_F(0x04beb599) /* 0.296559904 */, 19 }, + /* 7831 */ { MAD_F(0x04beea8d) /* 0.296610404 */, 19 }, + /* 7832 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 19 }, + /* 7833 */ { MAD_F(0x04bf5477) /* 0.296711413 */, 19 }, + /* 7834 */ { MAD_F(0x04bf896d) /* 0.296761920 */, 19 }, + /* 7835 */ { MAD_F(0x04bfbe64) /* 0.296812429 */, 19 }, + /* 7836 */ { MAD_F(0x04bff35b) /* 0.296862941 */, 19 }, + /* 7837 */ { MAD_F(0x04c02852) /* 0.296913455 */, 19 }, + /* 7838 */ { MAD_F(0x04c05d4b) /* 0.296963971 */, 19 }, + /* 7839 */ { MAD_F(0x04c09243) /* 0.297014489 */, 19 }, + + /* 7840 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 19 }, + /* 7841 */ { MAD_F(0x04c0fc37) /* 0.297115531 */, 19 }, + /* 7842 */ { MAD_F(0x04c13131) /* 0.297166056 */, 19 }, + /* 7843 */ { MAD_F(0x04c1662d) /* 0.297216582 */, 19 }, + /* 7844 */ { MAD_F(0x04c19b28) /* 0.297267111 */, 19 }, + /* 7845 */ { MAD_F(0x04c1d025) /* 0.297317642 */, 19 }, + /* 7846 */ { MAD_F(0x04c20521) /* 0.297368175 */, 19 }, + /* 7847 */ { MAD_F(0x04c23a1f) /* 0.297418710 */, 19 }, + /* 7848 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 19 }, + /* 7849 */ { MAD_F(0x04c2a41b) /* 0.297519787 */, 19 }, + /* 7850 */ { MAD_F(0x04c2d91b) /* 0.297570329 */, 19 }, + /* 7851 */ { MAD_F(0x04c30e1a) /* 0.297620873 */, 19 }, + /* 7852 */ { MAD_F(0x04c3431b) /* 0.297671418 */, 19 }, + /* 7853 */ { MAD_F(0x04c3781c) /* 0.297721967 */, 19 }, + /* 7854 */ { MAD_F(0x04c3ad1d) /* 0.297772517 */, 19 }, + /* 7855 */ { MAD_F(0x04c3e21f) /* 0.297823069 */, 19 }, + + /* 7856 */ { MAD_F(0x04c41722) /* 0.297873624 */, 19 }, + /* 7857 */ { MAD_F(0x04c44c25) /* 0.297924180 */, 19 }, + /* 7858 */ { MAD_F(0x04c48129) /* 0.297974739 */, 19 }, + /* 7859 */ { MAD_F(0x04c4b62d) /* 0.298025300 */, 19 }, + /* 7860 */ { MAD_F(0x04c4eb32) /* 0.298075863 */, 19 }, + /* 7861 */ { MAD_F(0x04c52038) /* 0.298126429 */, 19 }, + /* 7862 */ { MAD_F(0x04c5553e) /* 0.298176996 */, 19 }, + /* 7863 */ { MAD_F(0x04c58a44) /* 0.298227565 */, 19 }, + /* 7864 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 19 }, + /* 7865 */ { MAD_F(0x04c5f453) /* 0.298328711 */, 19 }, + /* 7866 */ { MAD_F(0x04c6295c) /* 0.298379287 */, 19 }, + /* 7867 */ { MAD_F(0x04c65e65) /* 0.298429865 */, 19 }, + /* 7868 */ { MAD_F(0x04c6936e) /* 0.298480445 */, 19 }, + /* 7869 */ { MAD_F(0x04c6c878) /* 0.298531028 */, 19 }, + /* 7870 */ { MAD_F(0x04c6fd83) /* 0.298581612 */, 19 }, + /* 7871 */ { MAD_F(0x04c7328e) /* 0.298632199 */, 19 }, + + /* 7872 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 19 }, + /* 7873 */ { MAD_F(0x04c79ca7) /* 0.298733379 */, 19 }, + /* 7874 */ { MAD_F(0x04c7d1b4) /* 0.298783972 */, 19 }, + /* 7875 */ { MAD_F(0x04c806c1) /* 0.298834567 */, 19 }, + /* 7876 */ { MAD_F(0x04c83bcf) /* 0.298885165 */, 19 }, + /* 7877 */ { MAD_F(0x04c870de) /* 0.298935764 */, 19 }, + /* 7878 */ { MAD_F(0x04c8a5ed) /* 0.298986366 */, 19 }, + /* 7879 */ { MAD_F(0x04c8dafd) /* 0.299036970 */, 19 }, + /* 7880 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 19 }, + /* 7881 */ { MAD_F(0x04c9451e) /* 0.299138184 */, 19 }, + /* 7882 */ { MAD_F(0x04c97a30) /* 0.299188794 */, 19 }, + /* 7883 */ { MAD_F(0x04c9af42) /* 0.299239406 */, 19 }, + /* 7884 */ { MAD_F(0x04c9e455) /* 0.299290021 */, 19 }, + /* 7885 */ { MAD_F(0x04ca1968) /* 0.299340638 */, 19 }, + /* 7886 */ { MAD_F(0x04ca4e7c) /* 0.299391256 */, 19 }, + /* 7887 */ { MAD_F(0x04ca8391) /* 0.299441877 */, 19 }, + + /* 7888 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 19 }, + /* 7889 */ { MAD_F(0x04caedbb) /* 0.299543126 */, 19 }, + /* 7890 */ { MAD_F(0x04cb22d1) /* 0.299593753 */, 19 }, + /* 7891 */ { MAD_F(0x04cb57e8) /* 0.299644382 */, 19 }, + /* 7892 */ { MAD_F(0x04cb8d00) /* 0.299695014 */, 19 }, + /* 7893 */ { MAD_F(0x04cbc217) /* 0.299745648 */, 19 }, + /* 7894 */ { MAD_F(0x04cbf730) /* 0.299796284 */, 19 }, + /* 7895 */ { MAD_F(0x04cc2c49) /* 0.299846922 */, 19 }, + /* 7896 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 19 }, + /* 7897 */ { MAD_F(0x04cc967d) /* 0.299948204 */, 19 }, + /* 7898 */ { MAD_F(0x04cccb98) /* 0.299998849 */, 19 }, + /* 7899 */ { MAD_F(0x04cd00b3) /* 0.300049495 */, 19 }, + /* 7900 */ { MAD_F(0x04cd35cf) /* 0.300100144 */, 19 }, + /* 7901 */ { MAD_F(0x04cd6aeb) /* 0.300150795 */, 19 }, + /* 7902 */ { MAD_F(0x04cda008) /* 0.300201448 */, 19 }, + /* 7903 */ { MAD_F(0x04cdd526) /* 0.300252103 */, 19 }, + + /* 7904 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 19 }, + /* 7905 */ { MAD_F(0x04ce3f63) /* 0.300353420 */, 19 }, + /* 7906 */ { MAD_F(0x04ce7482) /* 0.300404082 */, 19 }, + /* 7907 */ { MAD_F(0x04cea9a2) /* 0.300454745 */, 19 }, + /* 7908 */ { MAD_F(0x04cedec3) /* 0.300505411 */, 19 }, + /* 7909 */ { MAD_F(0x04cf13e4) /* 0.300556079 */, 19 }, + /* 7910 */ { MAD_F(0x04cf4906) /* 0.300606749 */, 19 }, + /* 7911 */ { MAD_F(0x04cf7e28) /* 0.300657421 */, 19 }, + /* 7912 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 19 }, + /* 7913 */ { MAD_F(0x04cfe86e) /* 0.300758772 */, 19 }, + /* 7914 */ { MAD_F(0x04d01d92) /* 0.300809451 */, 19 }, + /* 7915 */ { MAD_F(0x04d052b6) /* 0.300860132 */, 19 }, + /* 7916 */ { MAD_F(0x04d087db) /* 0.300910815 */, 19 }, + /* 7917 */ { MAD_F(0x04d0bd01) /* 0.300961500 */, 19 }, + /* 7918 */ { MAD_F(0x04d0f227) /* 0.301012187 */, 19 }, + /* 7919 */ { MAD_F(0x04d1274e) /* 0.301062876 */, 19 }, + + /* 7920 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 19 }, + /* 7921 */ { MAD_F(0x04d1919e) /* 0.301164261 */, 19 }, + /* 7922 */ { MAD_F(0x04d1c6c6) /* 0.301214957 */, 19 }, + /* 7923 */ { MAD_F(0x04d1fbef) /* 0.301265655 */, 19 }, + /* 7924 */ { MAD_F(0x04d23119) /* 0.301316355 */, 19 }, + /* 7925 */ { MAD_F(0x04d26643) /* 0.301367057 */, 19 }, + /* 7926 */ { MAD_F(0x04d29b6e) /* 0.301417761 */, 19 }, + /* 7927 */ { MAD_F(0x04d2d099) /* 0.301468468 */, 19 }, + /* 7928 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 19 }, + /* 7929 */ { MAD_F(0x04d33af2) /* 0.301569887 */, 19 }, + /* 7930 */ { MAD_F(0x04d3701f) /* 0.301620599 */, 19 }, + /* 7931 */ { MAD_F(0x04d3a54d) /* 0.301671314 */, 19 }, + /* 7932 */ { MAD_F(0x04d3da7b) /* 0.301722031 */, 19 }, + /* 7933 */ { MAD_F(0x04d40faa) /* 0.301772751 */, 19 }, + /* 7934 */ { MAD_F(0x04d444d9) /* 0.301823472 */, 19 }, + /* 7935 */ { MAD_F(0x04d47a09) /* 0.301874195 */, 19 }, + + /* 7936 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 19 }, + /* 7937 */ { MAD_F(0x04d4e46b) /* 0.301975649 */, 19 }, + /* 7938 */ { MAD_F(0x04d5199c) /* 0.302026378 */, 19 }, + /* 7939 */ { MAD_F(0x04d54ecf) /* 0.302077110 */, 19 }, + /* 7940 */ { MAD_F(0x04d58401) /* 0.302127845 */, 19 }, + /* 7941 */ { MAD_F(0x04d5b935) /* 0.302178581 */, 19 }, + /* 7942 */ { MAD_F(0x04d5ee69) /* 0.302229319 */, 19 }, + /* 7943 */ { MAD_F(0x04d6239d) /* 0.302280060 */, 19 }, + /* 7944 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 19 }, + /* 7945 */ { MAD_F(0x04d68e08) /* 0.302381547 */, 19 }, + /* 7946 */ { MAD_F(0x04d6c33e) /* 0.302432294 */, 19 }, + /* 7947 */ { MAD_F(0x04d6f875) /* 0.302483043 */, 19 }, + /* 7948 */ { MAD_F(0x04d72dad) /* 0.302533794 */, 19 }, + /* 7949 */ { MAD_F(0x04d762e5) /* 0.302584547 */, 19 }, + /* 7950 */ { MAD_F(0x04d7981d) /* 0.302635303 */, 19 }, + /* 7951 */ { MAD_F(0x04d7cd56) /* 0.302686060 */, 19 }, + + /* 7952 */ { MAD_F(0x04d80290) /* 0.302736820 */, 19 }, + /* 7953 */ { MAD_F(0x04d837ca) /* 0.302787581 */, 19 }, + /* 7954 */ { MAD_F(0x04d86d05) /* 0.302838345 */, 19 }, + /* 7955 */ { MAD_F(0x04d8a240) /* 0.302889111 */, 19 }, + /* 7956 */ { MAD_F(0x04d8d77c) /* 0.302939879 */, 19 }, + /* 7957 */ { MAD_F(0x04d90cb9) /* 0.302990650 */, 19 }, + /* 7958 */ { MAD_F(0x04d941f6) /* 0.303041422 */, 19 }, + /* 7959 */ { MAD_F(0x04d97734) /* 0.303092197 */, 19 }, + /* 7960 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 19 }, + /* 7961 */ { MAD_F(0x04d9e1b1) /* 0.303193752 */, 19 }, + /* 7962 */ { MAD_F(0x04da16f0) /* 0.303244533 */, 19 }, + /* 7963 */ { MAD_F(0x04da4c30) /* 0.303295316 */, 19 }, + /* 7964 */ { MAD_F(0x04da8171) /* 0.303346101 */, 19 }, + /* 7965 */ { MAD_F(0x04dab6b2) /* 0.303396889 */, 19 }, + /* 7966 */ { MAD_F(0x04daebf4) /* 0.303447678 */, 19 }, + /* 7967 */ { MAD_F(0x04db2136) /* 0.303498469 */, 19 }, + + /* 7968 */ { MAD_F(0x04db5679) /* 0.303549263 */, 19 }, + /* 7969 */ { MAD_F(0x04db8bbc) /* 0.303600059 */, 19 }, + /* 7970 */ { MAD_F(0x04dbc100) /* 0.303650857 */, 19 }, + /* 7971 */ { MAD_F(0x04dbf644) /* 0.303701657 */, 19 }, + /* 7972 */ { MAD_F(0x04dc2b8a) /* 0.303752459 */, 19 }, + /* 7973 */ { MAD_F(0x04dc60cf) /* 0.303803263 */, 19 }, + /* 7974 */ { MAD_F(0x04dc9616) /* 0.303854070 */, 19 }, + /* 7975 */ { MAD_F(0x04dccb5c) /* 0.303904878 */, 19 }, + /* 7976 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 19 }, + /* 7977 */ { MAD_F(0x04dd35ec) /* 0.304006502 */, 19 }, + /* 7978 */ { MAD_F(0x04dd6b34) /* 0.304057317 */, 19 }, + /* 7979 */ { MAD_F(0x04dda07d) /* 0.304108134 */, 19 }, + /* 7980 */ { MAD_F(0x04ddd5c7) /* 0.304158953 */, 19 }, + /* 7981 */ { MAD_F(0x04de0b11) /* 0.304209774 */, 19 }, + /* 7982 */ { MAD_F(0x04de405c) /* 0.304260597 */, 19 }, + /* 7983 */ { MAD_F(0x04de75a7) /* 0.304311423 */, 19 }, + + /* 7984 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 19 }, + /* 7985 */ { MAD_F(0x04dee040) /* 0.304413080 */, 19 }, + /* 7986 */ { MAD_F(0x04df158d) /* 0.304463912 */, 19 }, + /* 7987 */ { MAD_F(0x04df4adb) /* 0.304514746 */, 19 }, + /* 7988 */ { MAD_F(0x04df8029) /* 0.304565582 */, 19 }, + /* 7989 */ { MAD_F(0x04dfb578) /* 0.304616421 */, 19 }, + /* 7990 */ { MAD_F(0x04dfeac7) /* 0.304667261 */, 19 }, + /* 7991 */ { MAD_F(0x04e02017) /* 0.304718103 */, 19 }, + /* 7992 */ { MAD_F(0x04e05567) /* 0.304768948 */, 19 }, + /* 7993 */ { MAD_F(0x04e08ab8) /* 0.304819795 */, 19 }, + /* 7994 */ { MAD_F(0x04e0c00a) /* 0.304870644 */, 19 }, + /* 7995 */ { MAD_F(0x04e0f55c) /* 0.304921495 */, 19 }, + /* 7996 */ { MAD_F(0x04e12aaf) /* 0.304972348 */, 19 }, + /* 7997 */ { MAD_F(0x04e16002) /* 0.305023203 */, 19 }, + /* 7998 */ { MAD_F(0x04e19556) /* 0.305074060 */, 19 }, + /* 7999 */ { MAD_F(0x04e1caab) /* 0.305124920 */, 19 }, + + /* 8000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 19 }, + /* 8001 */ { MAD_F(0x04e23555) /* 0.305226645 */, 19 }, + /* 8002 */ { MAD_F(0x04e26aac) /* 0.305277511 */, 19 }, + /* 8003 */ { MAD_F(0x04e2a002) /* 0.305328379 */, 19 }, + /* 8004 */ { MAD_F(0x04e2d55a) /* 0.305379249 */, 19 }, + /* 8005 */ { MAD_F(0x04e30ab2) /* 0.305430121 */, 19 }, + /* 8006 */ { MAD_F(0x04e3400a) /* 0.305480995 */, 19 }, + /* 8007 */ { MAD_F(0x04e37563) /* 0.305531872 */, 19 }, + /* 8008 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 19 }, + /* 8009 */ { MAD_F(0x04e3e017) /* 0.305633631 */, 19 }, + /* 8010 */ { MAD_F(0x04e41572) /* 0.305684513 */, 19 }, + /* 8011 */ { MAD_F(0x04e44acd) /* 0.305735398 */, 19 }, + /* 8012 */ { MAD_F(0x04e48029) /* 0.305786285 */, 19 }, + /* 8013 */ { MAD_F(0x04e4b585) /* 0.305837174 */, 19 }, + /* 8014 */ { MAD_F(0x04e4eae2) /* 0.305888066 */, 19 }, + /* 8015 */ { MAD_F(0x04e52040) /* 0.305938959 */, 19 }, + + /* 8016 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 19 }, + /* 8017 */ { MAD_F(0x04e58afd) /* 0.306040752 */, 19 }, + /* 8018 */ { MAD_F(0x04e5c05c) /* 0.306091652 */, 19 }, + /* 8019 */ { MAD_F(0x04e5f5bc) /* 0.306142554 */, 19 }, + /* 8020 */ { MAD_F(0x04e62b1c) /* 0.306193457 */, 19 }, + /* 8021 */ { MAD_F(0x04e6607d) /* 0.306244364 */, 19 }, + /* 8022 */ { MAD_F(0x04e695df) /* 0.306295272 */, 19 }, + /* 8023 */ { MAD_F(0x04e6cb41) /* 0.306346182 */, 19 }, + /* 8024 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 19 }, + /* 8025 */ { MAD_F(0x04e73607) /* 0.306448009 */, 19 }, + /* 8026 */ { MAD_F(0x04e76b6b) /* 0.306498925 */, 19 }, + /* 8027 */ { MAD_F(0x04e7a0cf) /* 0.306549844 */, 19 }, + /* 8028 */ { MAD_F(0x04e7d634) /* 0.306600765 */, 19 }, + /* 8029 */ { MAD_F(0x04e80b99) /* 0.306651688 */, 19 }, + /* 8030 */ { MAD_F(0x04e84100) /* 0.306702613 */, 19 }, + /* 8031 */ { MAD_F(0x04e87666) /* 0.306753540 */, 19 }, + + /* 8032 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 19 }, + /* 8033 */ { MAD_F(0x04e8e135) /* 0.306855401 */, 19 }, + /* 8034 */ { MAD_F(0x04e9169e) /* 0.306906334 */, 19 }, + /* 8035 */ { MAD_F(0x04e94c07) /* 0.306957270 */, 19 }, + /* 8036 */ { MAD_F(0x04e98170) /* 0.307008208 */, 19 }, + /* 8037 */ { MAD_F(0x04e9b6da) /* 0.307059148 */, 19 }, + /* 8038 */ { MAD_F(0x04e9ec45) /* 0.307110090 */, 19 }, + /* 8039 */ { MAD_F(0x04ea21b0) /* 0.307161034 */, 19 }, + /* 8040 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 19 }, + /* 8041 */ { MAD_F(0x04ea8c88) /* 0.307262928 */, 19 }, + /* 8042 */ { MAD_F(0x04eac1f5) /* 0.307313879 */, 19 }, + /* 8043 */ { MAD_F(0x04eaf762) /* 0.307364831 */, 19 }, + /* 8044 */ { MAD_F(0x04eb2cd0) /* 0.307415786 */, 19 }, + /* 8045 */ { MAD_F(0x04eb623f) /* 0.307466743 */, 19 }, + /* 8046 */ { MAD_F(0x04eb97ae) /* 0.307517702 */, 19 }, + /* 8047 */ { MAD_F(0x04ebcd1e) /* 0.307568663 */, 19 }, + + /* 8048 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 19 }, + /* 8049 */ { MAD_F(0x04ec37ff) /* 0.307670591 */, 19 }, + /* 8050 */ { MAD_F(0x04ec6d71) /* 0.307721558 */, 19 }, + /* 8051 */ { MAD_F(0x04eca2e3) /* 0.307772528 */, 19 }, + /* 8052 */ { MAD_F(0x04ecd855) /* 0.307823499 */, 19 }, + /* 8053 */ { MAD_F(0x04ed0dc8) /* 0.307874473 */, 19 }, + /* 8054 */ { MAD_F(0x04ed433c) /* 0.307925449 */, 19 }, + /* 8055 */ { MAD_F(0x04ed78b0) /* 0.307976426 */, 19 }, + /* 8056 */ { MAD_F(0x04edae25) /* 0.308027406 */, 19 }, + /* 8057 */ { MAD_F(0x04ede39a) /* 0.308078389 */, 19 }, + /* 8058 */ { MAD_F(0x04ee1910) /* 0.308129373 */, 19 }, + /* 8059 */ { MAD_F(0x04ee4e87) /* 0.308180359 */, 19 }, + /* 8060 */ { MAD_F(0x04ee83fe) /* 0.308231347 */, 19 }, + /* 8061 */ { MAD_F(0x04eeb976) /* 0.308282338 */, 19 }, + /* 8062 */ { MAD_F(0x04eeeeee) /* 0.308333331 */, 19 }, + /* 8063 */ { MAD_F(0x04ef2467) /* 0.308384325 */, 19 }, + + /* 8064 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 19 }, + /* 8065 */ { MAD_F(0x04ef8f5a) /* 0.308486321 */, 19 }, + /* 8066 */ { MAD_F(0x04efc4d5) /* 0.308537322 */, 19 }, + /* 8067 */ { MAD_F(0x04effa50) /* 0.308588325 */, 19 }, + /* 8068 */ { MAD_F(0x04f02fcb) /* 0.308639331 */, 19 }, + /* 8069 */ { MAD_F(0x04f06547) /* 0.308690338 */, 19 }, + /* 8070 */ { MAD_F(0x04f09ac4) /* 0.308741348 */, 19 }, + /* 8071 */ { MAD_F(0x04f0d041) /* 0.308792359 */, 19 }, + /* 8072 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 19 }, + /* 8073 */ { MAD_F(0x04f13b3e) /* 0.308894389 */, 19 }, + /* 8074 */ { MAD_F(0x04f170bd) /* 0.308945407 */, 19 }, + /* 8075 */ { MAD_F(0x04f1a63c) /* 0.308996427 */, 19 }, + /* 8076 */ { MAD_F(0x04f1dbbd) /* 0.309047449 */, 19 }, + /* 8077 */ { MAD_F(0x04f2113d) /* 0.309098473 */, 19 }, + /* 8078 */ { MAD_F(0x04f246bf) /* 0.309149499 */, 19 }, + /* 8079 */ { MAD_F(0x04f27c40) /* 0.309200528 */, 19 }, + + /* 8080 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 19 }, + /* 8081 */ { MAD_F(0x04f2e746) /* 0.309302591 */, 19 }, + /* 8082 */ { MAD_F(0x04f31cc9) /* 0.309353626 */, 19 }, + /* 8083 */ { MAD_F(0x04f3524d) /* 0.309404663 */, 19 }, + /* 8084 */ { MAD_F(0x04f387d2) /* 0.309455702 */, 19 }, + /* 8085 */ { MAD_F(0x04f3bd57) /* 0.309506743 */, 19 }, + /* 8086 */ { MAD_F(0x04f3f2dd) /* 0.309557786 */, 19 }, + /* 8087 */ { MAD_F(0x04f42864) /* 0.309608831 */, 19 }, + /* 8088 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 19 }, + /* 8089 */ { MAD_F(0x04f49372) /* 0.309710928 */, 19 }, + /* 8090 */ { MAD_F(0x04f4c8fa) /* 0.309761980 */, 19 }, + /* 8091 */ { MAD_F(0x04f4fe83) /* 0.309813033 */, 19 }, + /* 8092 */ { MAD_F(0x04f5340c) /* 0.309864089 */, 19 }, + /* 8093 */ { MAD_F(0x04f56996) /* 0.309915147 */, 19 }, + /* 8094 */ { MAD_F(0x04f59f20) /* 0.309966207 */, 19 }, + /* 8095 */ { MAD_F(0x04f5d4ab) /* 0.310017269 */, 19 }, + + /* 8096 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 19 }, + /* 8097 */ { MAD_F(0x04f63fc2) /* 0.310119400 */, 19 }, + /* 8098 */ { MAD_F(0x04f6754f) /* 0.310170468 */, 19 }, + /* 8099 */ { MAD_F(0x04f6aadc) /* 0.310221539 */, 19 }, + /* 8100 */ { MAD_F(0x04f6e06a) /* 0.310272611 */, 19 }, + /* 8101 */ { MAD_F(0x04f715f8) /* 0.310323686 */, 19 }, + /* 8102 */ { MAD_F(0x04f74b87) /* 0.310374763 */, 19 }, + /* 8103 */ { MAD_F(0x04f78116) /* 0.310425842 */, 19 }, + /* 8104 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 19 }, + /* 8105 */ { MAD_F(0x04f7ec37) /* 0.310528006 */, 19 }, + /* 8106 */ { MAD_F(0x04f821c8) /* 0.310579091 */, 19 }, + /* 8107 */ { MAD_F(0x04f85759) /* 0.310630179 */, 19 }, + /* 8108 */ { MAD_F(0x04f88cec) /* 0.310681268 */, 19 }, + /* 8109 */ { MAD_F(0x04f8c27e) /* 0.310732360 */, 19 }, + /* 8110 */ { MAD_F(0x04f8f812) /* 0.310783453 */, 19 }, + /* 8111 */ { MAD_F(0x04f92da6) /* 0.310834549 */, 19 }, + + /* 8112 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 19 }, + /* 8113 */ { MAD_F(0x04f998cf) /* 0.310936747 */, 19 }, + /* 8114 */ { MAD_F(0x04f9ce65) /* 0.310987849 */, 19 }, + /* 8115 */ { MAD_F(0x04fa03fb) /* 0.311038953 */, 19 }, + /* 8116 */ { MAD_F(0x04fa3992) /* 0.311090059 */, 19 }, + /* 8117 */ { MAD_F(0x04fa6f29) /* 0.311141168 */, 19 }, + /* 8118 */ { MAD_F(0x04faa4c1) /* 0.311192278 */, 19 }, + /* 8119 */ { MAD_F(0x04fada59) /* 0.311243390 */, 19 }, + /* 8120 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 19 }, + /* 8121 */ { MAD_F(0x04fb458c) /* 0.311345622 */, 19 }, + /* 8122 */ { MAD_F(0x04fb7b26) /* 0.311396741 */, 19 }, + /* 8123 */ { MAD_F(0x04fbb0c1) /* 0.311447862 */, 19 }, + /* 8124 */ { MAD_F(0x04fbe65c) /* 0.311498985 */, 19 }, + /* 8125 */ { MAD_F(0x04fc1bf8) /* 0.311550110 */, 19 }, + /* 8126 */ { MAD_F(0x04fc5194) /* 0.311601237 */, 19 }, + /* 8127 */ { MAD_F(0x04fc8731) /* 0.311652366 */, 19 }, + + /* 8128 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 19 }, + /* 8129 */ { MAD_F(0x04fcf26c) /* 0.311754631 */, 19 }, + /* 8130 */ { MAD_F(0x04fd280b) /* 0.311805767 */, 19 }, + /* 8131 */ { MAD_F(0x04fd5daa) /* 0.311856905 */, 19 }, + /* 8132 */ { MAD_F(0x04fd934a) /* 0.311908044 */, 19 }, + /* 8133 */ { MAD_F(0x04fdc8ea) /* 0.311959186 */, 19 }, + /* 8134 */ { MAD_F(0x04fdfe8b) /* 0.312010330 */, 19 }, + /* 8135 */ { MAD_F(0x04fe342c) /* 0.312061476 */, 19 }, + /* 8136 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 19 }, + /* 8137 */ { MAD_F(0x04fe9f71) /* 0.312163775 */, 19 }, + /* 8138 */ { MAD_F(0x04fed514) /* 0.312214927 */, 19 }, + /* 8139 */ { MAD_F(0x04ff0ab8) /* 0.312266082 */, 19 }, + /* 8140 */ { MAD_F(0x04ff405c) /* 0.312317238 */, 19 }, + /* 8141 */ { MAD_F(0x04ff7601) /* 0.312368397 */, 19 }, + /* 8142 */ { MAD_F(0x04ffaba6) /* 0.312419558 */, 19 }, + /* 8143 */ { MAD_F(0x04ffe14c) /* 0.312470720 */, 19 }, + + /* 8144 */ { MAD_F(0x050016f3) /* 0.312521885 */, 19 }, + /* 8145 */ { MAD_F(0x05004c9a) /* 0.312573052 */, 19 }, + /* 8146 */ { MAD_F(0x05008241) /* 0.312624222 */, 19 }, + /* 8147 */ { MAD_F(0x0500b7e9) /* 0.312675393 */, 19 }, + /* 8148 */ { MAD_F(0x0500ed92) /* 0.312726566 */, 19 }, + /* 8149 */ { MAD_F(0x0501233b) /* 0.312777742 */, 19 }, + /* 8150 */ { MAD_F(0x050158e5) /* 0.312828919 */, 19 }, + /* 8151 */ { MAD_F(0x05018e90) /* 0.312880099 */, 19 }, + /* 8152 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 19 }, + /* 8153 */ { MAD_F(0x0501f9e6) /* 0.312982464 */, 19 }, + /* 8154 */ { MAD_F(0x05022f92) /* 0.313033650 */, 19 }, + /* 8155 */ { MAD_F(0x0502653f) /* 0.313084838 */, 19 }, + /* 8156 */ { MAD_F(0x05029aec) /* 0.313136028 */, 19 }, + /* 8157 */ { MAD_F(0x0502d09a) /* 0.313187220 */, 19 }, + /* 8158 */ { MAD_F(0x05030648) /* 0.313238414 */, 19 }, + /* 8159 */ { MAD_F(0x05033bf7) /* 0.313289611 */, 19 }, + + /* 8160 */ { MAD_F(0x050371a7) /* 0.313340809 */, 19 }, + /* 8161 */ { MAD_F(0x0503a757) /* 0.313392010 */, 19 }, + /* 8162 */ { MAD_F(0x0503dd07) /* 0.313443212 */, 19 }, + /* 8163 */ { MAD_F(0x050412b9) /* 0.313494417 */, 19 }, + /* 8164 */ { MAD_F(0x0504486a) /* 0.313545624 */, 19 }, + /* 8165 */ { MAD_F(0x05047e1d) /* 0.313596833 */, 19 }, + /* 8166 */ { MAD_F(0x0504b3cf) /* 0.313648044 */, 19 }, + /* 8167 */ { MAD_F(0x0504e983) /* 0.313699257 */, 19 }, + /* 8168 */ { MAD_F(0x05051f37) /* 0.313750472 */, 19 }, + /* 8169 */ { MAD_F(0x050554eb) /* 0.313801689 */, 19 }, + /* 8170 */ { MAD_F(0x05058aa0) /* 0.313852909 */, 19 }, + /* 8171 */ { MAD_F(0x0505c056) /* 0.313904130 */, 19 }, + /* 8172 */ { MAD_F(0x0505f60c) /* 0.313955354 */, 19 }, + /* 8173 */ { MAD_F(0x05062bc3) /* 0.314006579 */, 19 }, + /* 8174 */ { MAD_F(0x0506617a) /* 0.314057807 */, 19 }, + /* 8175 */ { MAD_F(0x05069732) /* 0.314109037 */, 19 }, + + /* 8176 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 19 }, + /* 8177 */ { MAD_F(0x050702a4) /* 0.314211502 */, 19 }, + /* 8178 */ { MAD_F(0x0507385d) /* 0.314262739 */, 19 }, + /* 8179 */ { MAD_F(0x05076e17) /* 0.314313977 */, 19 }, + /* 8180 */ { MAD_F(0x0507a3d2) /* 0.314365217 */, 19 }, + /* 8181 */ { MAD_F(0x0507d98d) /* 0.314416459 */, 19 }, + /* 8182 */ { MAD_F(0x05080f49) /* 0.314467704 */, 19 }, + /* 8183 */ { MAD_F(0x05084506) /* 0.314518950 */, 19 }, + /* 8184 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 19 }, + /* 8185 */ { MAD_F(0x0508b080) /* 0.314621449 */, 19 }, + /* 8186 */ { MAD_F(0x0508e63e) /* 0.314672702 */, 19 }, + /* 8187 */ { MAD_F(0x05091bfd) /* 0.314723957 */, 19 }, + /* 8188 */ { MAD_F(0x050951bc) /* 0.314775214 */, 19 }, + /* 8189 */ { MAD_F(0x0509877c) /* 0.314826473 */, 19 }, + /* 8190 */ { MAD_F(0x0509bd3c) /* 0.314877734 */, 19 }, + /* 8191 */ { MAD_F(0x0509f2fd) /* 0.314928997 */, 19 }, + + /* 8192 */ { MAD_F(0x050a28be) /* 0.314980262 */, 19 }, + /* 8193 */ { MAD_F(0x050a5e80) /* 0.315031530 */, 19 }, + /* 8194 */ { MAD_F(0x050a9443) /* 0.315082799 */, 19 }, + /* 8195 */ { MAD_F(0x050aca06) /* 0.315134071 */, 19 }, + /* 8196 */ { MAD_F(0x050affc9) /* 0.315185344 */, 19 }, + /* 8197 */ { MAD_F(0x050b358e) /* 0.315236620 */, 19 }, + /* 8198 */ { MAD_F(0x050b6b52) /* 0.315287898 */, 19 }, + /* 8199 */ { MAD_F(0x050ba118) /* 0.315339178 */, 19 }, + /* 8200 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 19 }, + /* 8201 */ { MAD_F(0x050c0ca4) /* 0.315441744 */, 19 }, + /* 8202 */ { MAD_F(0x050c426b) /* 0.315493030 */, 19 }, + /* 8203 */ { MAD_F(0x050c7833) /* 0.315544318 */, 19 }, + /* 8204 */ { MAD_F(0x050cadfb) /* 0.315595608 */, 19 }, + /* 8205 */ { MAD_F(0x050ce3c4) /* 0.315646901 */, 19 }, + /* 8206 */ { MAD_F(0x050d198d) /* 0.315698195 */, 19 } diff --git a/core/multimedia/opieplayer/libmad/sf_table.dat b/core/multimedia/opieplayer/libmad/sf_table.dat new file mode 100644 index 0000000..18e6202 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/sf_table.dat @@ -0,0 +1,100 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +/* + * These are the scalefactor values for Layer I and Layer II. + * The values are from Table B.1 of ISO/IEC 11172-3. + * + * There is some error introduced by the 32-bit fixed-point representation; + * the amount of error is shown. For 16-bit PCM output, this shouldn't be + * too much of a problem. + */ + + MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */ + MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */ + MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */ + MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */ + MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */ + MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */ + MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */ + MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */ + + MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */ + MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */ + MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */ + MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */ + MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */ + MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */ + MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */ + MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */ + + MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */ + MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */ + MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */ + MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */ + MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */ + MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */ + MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */ + MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */ + + MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */ + MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */ + MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */ + MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */ + MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */ + MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */ + MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */ + MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */ + + MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */ + MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */ + MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */ + MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */ + MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */ + MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */ + MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */ + MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */ + + MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */ + MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */ + MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */ + MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */ + MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */ + MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */ + MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */ + MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */ + + MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */ + MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */ + MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */ + MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */ + MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */ + MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */ + MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */ + MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */ + + MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */ + MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */ + MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */ + MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */ + MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */ + MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */ + MAD_F(0x00000143) /* 0.000001201554 => 0.000001203269, e -0.000000001714 */ diff --git a/core/multimedia/opieplayer/libmad/stream.c b/core/multimedia/opieplayer/libmad/stream.c new file mode 100644 index 0000000..dea7b8e --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/stream.c @@ -0,0 +1,123 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# include + +# include "bit.h" +# include "stream.h" + +/* + * NAME: stream->init() + * DESCRIPTION: initialize stream struct + */ +void mad_stream_init(struct mad_stream *stream) +{ + stream->buffer = 0; + stream->bufend = 0; + stream->skiplen = 0; + + stream->sync = 0; + stream->freerate = 0; + + stream->this_frame = 0; + stream->next_frame = 0; + mad_bit_init(&stream->ptr, 0); + + mad_bit_init(&stream->anc_ptr, 0); + stream->anc_bitlen = 0; + + stream->main_data = 0; + stream->md_len = 0; + + stream->options = 0; + stream->error = 0; +} + +/* + * NAME: stream->finish() + * DESCRIPTION: deallocate any dynamic memory associated with stream + */ +void mad_stream_finish(struct mad_stream *stream) +{ + if (stream->main_data) { + free(stream->main_data); + stream->main_data = 0; + } + + mad_bit_finish(&stream->anc_ptr); + mad_bit_finish(&stream->ptr); +} + +/* + * NAME: stream->buffer() + * DESCRIPTION: set stream buffer pointers + */ +void mad_stream_buffer(struct mad_stream *stream, + unsigned char const *buffer, unsigned long length) +{ + stream->buffer = buffer; + stream->bufend = buffer + length; + + stream->this_frame = buffer; + stream->next_frame = buffer; + + stream->sync = 1; + + mad_bit_init(&stream->ptr, buffer); +} + +/* + * NAME: stream->skip() + * DESCRIPTION: arrange to skip bytes before the next frame + */ +void mad_stream_skip(struct mad_stream *stream, unsigned long length) +{ + stream->skiplen += length; +} + +/* + * NAME: stream->sync() + * DESCRIPTION: locate the next stream sync word + */ +int mad_stream_sync(struct mad_stream *stream) +{ + register unsigned char const *ptr, *end; + + ptr = mad_bit_nextbyte(&stream->ptr); + end = stream->bufend; + + while (ptr < end - 1 && + !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) + ++ptr; + + if (end - ptr < MAD_BUFFER_GUARD) + return -1; + + mad_bit_init(&stream->ptr, ptr); + + return 0; +} diff --git a/core/multimedia/opieplayer/libmad/stream.h b/core/multimedia/opieplayer/libmad/stream.h new file mode 100644 index 0000000..cf3280e --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/stream.h @@ -0,0 +1,102 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_STREAM_H +# define LIBMAD_STREAM_H + +# include "bit.h" + +# define MAD_BUFFER_GUARD 8 +# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) + +enum mad_error { + MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ + MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ + + MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ + + MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ + MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ + MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ + MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ + MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ + + MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ + MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ + MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ + MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ + MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ + MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ + MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ + MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ + MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ + MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ + MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ + MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ +}; + +# define MAD_RECOVERABLE(error) ((error) & 0xff00) + +struct mad_stream { + unsigned char const *buffer; /* input bitstream buffer */ + unsigned char const *bufend; /* end of buffer */ + unsigned long skiplen; /* bytes to skip before next frame */ + + int sync; /* stream sync found */ + unsigned long freerate; /* free bitrate (fixed) */ + + unsigned char const *this_frame; /* start of current frame */ + unsigned char const *next_frame; /* start of next frame */ + struct mad_bitptr ptr; /* current processing bit pointer */ + + struct mad_bitptr anc_ptr; /* ancillary bits pointer */ + unsigned int anc_bitlen; /* number of ancillary bits */ + + unsigned char (*main_data)[MAD_BUFFER_MDLEN]; + /* Layer III main_data() */ + unsigned int md_len; /* bytes in main_data */ + + int options; /* decoding options (see below) */ + enum mad_error error; /* error code (see above) */ +}; + +enum { + MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ + MAD_OPTION_HALFSAMPLERATE = 0x0002, /* generate PCM at 1/2 sample rate */ +# if 0 /* not yet implemented */ + MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ + MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ + MAD_OPTION_SINGLECHANNEL = 0x0030, /* combine channels */ +# endif +}; + +void mad_stream_init(struct mad_stream *); +void mad_stream_finish(struct mad_stream *); + +# define mad_stream_options(stream, opts) ((stream)->options = (opts)) + +void mad_stream_buffer(struct mad_stream *, + unsigned char const *, unsigned long); +void mad_stream_skip(struct mad_stream *, unsigned long); + +int mad_stream_sync(struct mad_stream *); + +# endif diff --git a/core/multimedia/opieplayer/libmad/synth.c b/core/multimedia/opieplayer/libmad/synth.c new file mode 100644 index 0000000..e1914c9 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/synth.c @@ -0,0 +1,855 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# include "fixed.h" +# include "frame.h" +# include "synth.h" + +/* + * NAME: synth->init() + * DESCRIPTION: initialize synth struct + */ +void mad_synth_init(struct mad_synth *synth) +{ + mad_synth_mute(synth); + + synth->phase = 0; + + synth->pcm.samplerate = 0; + synth->pcm.channels = 0; + synth->pcm.length = 0; +} + +/* + * NAME: synth->mute() + * DESCRIPTION: zero all polyphase filterbank values, resetting synthesis + */ +void mad_synth_mute(struct mad_synth *synth) +{ + unsigned int ch, s, v; + + for (ch = 0; ch < 2; ++ch) { + for (s = 0; s < 16; ++s) { + for (v = 0; v < 8; ++v) { + synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] = + synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0; + } + } + } +} + +/* + * An optional optimization called here the Subband Synthesis Optimization + * (SSO) improves the performance of subband synthesis at the expense of + * accuracy. + * + * The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such + * that extra scaling and rounding are not necessary. This often allows the + * compiler to use faster 32-bit multiply-accumulate instructions instead of + * explicit 64-bit multiply, shift, and add instructions. + * + * SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t + * values requires the result to be right-shifted 28 bits to be properly + * scaled to the same fixed-point format. Right shifts can be applied at any + * time to either operand or to the result, so the optimization involves + * careful placement of these shifts to minimize the loss of accuracy. + * + * First, a 14-bit shift is applied with rounding at compile-time to the D[] + * table of coefficients for the subband synthesis window. This only loses 2 + * bits of accuracy because the lower 12 bits are always zero. A second + * 12-bit shift occurs after the DCT calculation. This loses 12 bits of + * accuracy. Finally, a third 2-bit shift occurs just before the sample is + * saved in the PCM buffer. 14 + 12 + 2 == 28 bits. + */ + +/* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */ + +# if defined(FPM_DEFAULT) && !defined(OPT_SSO) +# define OPT_SSO +# endif + +/* second SSO shift, with rounding */ + +# if defined(OPT_SSO) +# define SHIFT(x) (((x) + (1L << 11)) >> 12) +# else +# define SHIFT(x) (x) +# endif + +/* possible DCT speed optimization */ + +# if defined(OPT_SPEED) && defined(MAD_F_MLX) +# define OPT_DCTO +# define MUL(x, y) \ + ({ mad_fixed64hi_t hi; \ + mad_fixed64lo_t lo; \ + MAD_F_MLX(hi, lo, (x), (y)); \ + hi << (32 - MAD_F_SCALEBITS - 3); \ + }) +# else +# undef OPT_DCTO +# define MUL(x, y) mad_f_mul((x), (y)) +# endif + +/* + * NAME: dct32() + * DESCRIPTION: perform fast in[32]->out[32] DCT + */ +static +void dct32(mad_fixed_t const in[32], unsigned int slot, + mad_fixed_t lo[16][8], mad_fixed_t hi[16][8]) +{ + mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; + mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; + mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23; + mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31; + mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39; + mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47; + mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55; + mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63; + mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71; + mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79; + mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87; + mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95; + mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103; + mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111; + mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119; + mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127; + mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135; + mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143; + mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151; + mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159; + mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167; + mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175; + mad_fixed_t t176; + + /* costab[i] = cos(PI / (2 * 32) * i) */ + +# if defined(OPT_DCTO) + enum { + costab1 = MAD_F(0x7fd8878e), + costab2 = MAD_F(0x7f62368f), + costab3 = MAD_F(0x7e9d55fc), + costab4 = MAD_F(0x7d8a5f40), + costab5 = MAD_F(0x7c29fbee), + costab6 = MAD_F(0x7a7d055b), + costab7 = MAD_F(0x78848414), + costab8 = MAD_F(0x7641af3d), + costab9 = MAD_F(0x73b5ebd1), + costab10 = MAD_F(0x70e2cbc6), + costab11 = MAD_F(0x6dca0d14), + costab12 = MAD_F(0x6a6d98a4), + costab13 = MAD_F(0x66cf8120), + costab14 = MAD_F(0x62f201ac), + costab15 = MAD_F(0x5ed77c8a), + costab16 = MAD_F(0x5a82799a), + costab17 = MAD_F(0x55f5a4d2), + costab18 = MAD_F(0x5133cc94), + costab19 = MAD_F(0x4c3fdff4), + costab20 = MAD_F(0x471cece7), + costab21 = MAD_F(0x41ce1e65), + costab22 = MAD_F(0x3c56ba70), + costab23 = MAD_F(0x36ba2014), + costab24 = MAD_F(0x30fbc54d), + costab25 = MAD_F(0x2b1f34eb), + costab26 = MAD_F(0x25280c5e), + costab27 = MAD_F(0x1f19f97b), + costab28 = MAD_F(0x18f8b83c), + costab29 = MAD_F(0x12c8106f), + costab30 = MAD_F(0x0c8bd35e), + costab31 = MAD_F(0x0647d97c) + }; +# else + enum { + costab1 = MAD_F(0x0ffb10f2), /* 0.998795456 */ + costab2 = MAD_F(0x0fec46d2), /* 0.995184727 */ + costab3 = MAD_F(0x0fd3aac0), /* 0.989176510 */ + costab4 = MAD_F(0x0fb14be8), /* 0.980785280 */ + costab5 = MAD_F(0x0f853f7e), /* 0.970031253 */ + costab6 = MAD_F(0x0f4fa0ab), /* 0.956940336 */ + costab7 = MAD_F(0x0f109082), /* 0.941544065 */ + costab8 = MAD_F(0x0ec835e8), /* 0.923879533 */ + costab9 = MAD_F(0x0e76bd7a), /* 0.903989293 */ + costab10 = MAD_F(0x0e1c5979), /* 0.881921264 */ + costab11 = MAD_F(0x0db941a3), /* 0.857728610 */ + costab12 = MAD_F(0x0d4db315), /* 0.831469612 */ + costab13 = MAD_F(0x0cd9f024), /* 0.803207531 */ + costab14 = MAD_F(0x0c5e4036), /* 0.773010453 */ + costab15 = MAD_F(0x0bdaef91), /* 0.740951125 */ + costab16 = MAD_F(0x0b504f33), /* 0.707106781 */ + costab17 = MAD_F(0x0abeb49a), /* 0.671558955 */ + costab18 = MAD_F(0x0a267993), /* 0.634393284 */ + costab19 = MAD_F(0x0987fbfe), /* 0.595699304 */ + costab20 = MAD_F(0x08e39d9d), /* 0.555570233 */ + costab21 = MAD_F(0x0839c3cd), /* 0.514102744 */ + costab22 = MAD_F(0x078ad74e), /* 0.471396737 */ + costab23 = MAD_F(0x06d74402), /* 0.427555093 */ + costab24 = MAD_F(0x061f78aa), /* 0.382683432 */ + costab25 = MAD_F(0x0563e69d), /* 0.336889853 */ + costab26 = MAD_F(0x04a5018c), /* 0.290284677 */ + costab27 = MAD_F(0x03e33f2f), /* 0.242980180 */ + costab28 = MAD_F(0x031f1708), /* 0.195090322 */ + costab29 = MAD_F(0x0259020e), /* 0.146730474 */ + costab30 = MAD_F(0x01917a6c), /* 0.098017140 */ + costab31 = MAD_F(0x00c8fb30) /* 0.049067674 */ + }; +# endif + + t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1); + t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31); + + t41 = t16 + t17; + t59 = MUL(t16 - t17, costab2); + t33 = t0 + t1; + t50 = MUL(t0 - t1, costab2); + + t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15); + t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17); + + t42 = t18 + t19; + t60 = MUL(t18 - t19, costab30); + t34 = t2 + t3; + t51 = MUL(t2 - t3, costab30); + + t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7); + t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25); + + t43 = t20 + t21; + t61 = MUL(t20 - t21, costab14); + t35 = t4 + t5; + t52 = MUL(t4 - t5, costab14); + + t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9); + t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23); + + t44 = t22 + t23; + t62 = MUL(t22 - t23, costab18); + t36 = t6 + t7; + t53 = MUL(t6 - t7, costab18); + + t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3); + t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29); + + t45 = t24 + t25; + t63 = MUL(t24 - t25, costab6); + t37 = t8 + t9; + t54 = MUL(t8 - t9, costab6); + + t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13); + t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19); + + t46 = t26 + t27; + t64 = MUL(t26 - t27, costab26); + t38 = t10 + t11; + t55 = MUL(t10 - t11, costab26); + + t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5); + t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27); + + t47 = t28 + t29; + t65 = MUL(t28 - t29, costab10); + t39 = t12 + t13; + t56 = MUL(t12 - t13, costab10); + + t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11); + t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21); + + t48 = t30 + t31; + t66 = MUL(t30 - t31, costab22); + t40 = t14 + t15; + t57 = MUL(t14 - t15, costab22); + + t69 = t33 + t34; t89 = MUL(t33 - t34, costab4); + t70 = t35 + t36; t90 = MUL(t35 - t36, costab28); + t71 = t37 + t38; t91 = MUL(t37 - t38, costab12); + t72 = t39 + t40; t92 = MUL(t39 - t40, costab20); + t73 = t41 + t42; t94 = MUL(t41 - t42, costab4); + t74 = t43 + t44; t95 = MUL(t43 - t44, costab28); + t75 = t45 + t46; t96 = MUL(t45 - t46, costab12); + t76 = t47 + t48; t97 = MUL(t47 - t48, costab20); + + t78 = t50 + t51; t100 = MUL(t50 - t51, costab4); + t79 = t52 + t53; t101 = MUL(t52 - t53, costab28); + t80 = t54 + t55; t102 = MUL(t54 - t55, costab12); + t81 = t56 + t57; t103 = MUL(t56 - t57, costab20); + + t83 = t59 + t60; t106 = MUL(t59 - t60, costab4); + t84 = t61 + t62; t107 = MUL(t61 - t62, costab28); + t85 = t63 + t64; t108 = MUL(t63 - t64, costab12); + t86 = t65 + t66; t109 = MUL(t65 - t66, costab20); + + t113 = t69 + t70; + t114 = t71 + t72; + + /* 0 */ hi[15][slot] = SHIFT(t113 + t114); + /* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16)); + + t115 = t73 + t74; + t116 = t75 + t76; + + t32 = t115 + t116; + + /* 1 */ hi[14][slot] = SHIFT(t32); + + t118 = t78 + t79; + t119 = t80 + t81; + + t58 = t118 + t119; + + /* 2 */ hi[13][slot] = SHIFT(t58); + + t121 = t83 + t84; + t122 = t85 + t86; + + t67 = t121 + t122; + + t49 = (t67 << 1) - t32; + + /* 3 */ hi[12][slot] = SHIFT(t49); + + t125 = t89 + t90; + t126 = t91 + t92; + + t93 = t125 + t126; + + /* 4 */ hi[11][slot] = SHIFT(t93); + + t128 = t94 + t95; + t129 = t96 + t97; + + t98 = t128 + t129; + + t68 = (t98 << 1) - t49; + + /* 5 */ hi[10][slot] = SHIFT(t68); + + t132 = t100 + t101; + t133 = t102 + t103; + + t104 = t132 + t133; + + t82 = (t104 << 1) - t58; + + /* 6 */ hi[ 9][slot] = SHIFT(t82); + + t136 = t106 + t107; + t137 = t108 + t109; + + t110 = t136 + t137; + + t87 = (t110 << 1) - t67; + + t77 = (t87 << 1) - t68; + + /* 7 */ hi[ 8][slot] = SHIFT(t77); + + t141 = MUL(t69 - t70, costab8); + t142 = MUL(t71 - t72, costab24); + t143 = t141 + t142; + + /* 8 */ hi[ 7][slot] = SHIFT(t143); + /* 24 */ lo[ 8][slot] = + SHIFT((MUL(t141 - t142, costab16) << 1) - t143); + + t144 = MUL(t73 - t74, costab8); + t145 = MUL(t75 - t76, costab24); + t146 = t144 + t145; + + t88 = (t146 << 1) - t77; + + /* 9 */ hi[ 6][slot] = SHIFT(t88); + + t148 = MUL(t78 - t79, costab8); + t149 = MUL(t80 - t81, costab24); + t150 = t148 + t149; + + t105 = (t150 << 1) - t82; + + /* 10 */ hi[ 5][slot] = SHIFT(t105); + + t152 = MUL(t83 - t84, costab8); + t153 = MUL(t85 - t86, costab24); + t154 = t152 + t153; + + t111 = (t154 << 1) - t87; + + t99 = (t111 << 1) - t88; + + /* 11 */ hi[ 4][slot] = SHIFT(t99); + + t157 = MUL(t89 - t90, costab8); + t158 = MUL(t91 - t92, costab24); + t159 = t157 + t158; + + t127 = (t159 << 1) - t93; + + /* 12 */ hi[ 3][slot] = SHIFT(t127); + + t160 = (MUL(t125 - t126, costab16) << 1) - t127; + + /* 20 */ lo[ 4][slot] = SHIFT(t160); + /* 28 */ lo[12][slot] = + SHIFT((((MUL(t157 - t158, costab16) << 1) - t159) << 1) - t160); + + t161 = MUL(t94 - t95, costab8); + t162 = MUL(t96 - t97, costab24); + t163 = t161 + t162; + + t130 = (t163 << 1) - t98; + + t112 = (t130 << 1) - t99; + + /* 13 */ hi[ 2][slot] = SHIFT(t112); + + t164 = (MUL(t128 - t129, costab16) << 1) - t130; + + t166 = MUL(t100 - t101, costab8); + t167 = MUL(t102 - t103, costab24); + t168 = t166 + t167; + + t134 = (t168 << 1) - t104; + + t120 = (t134 << 1) - t105; + + /* 14 */ hi[ 1][slot] = SHIFT(t120); + + t135 = (MUL(t118 - t119, costab16) << 1) - t120; + + /* 18 */ lo[ 2][slot] = SHIFT(t135); + + t169 = (MUL(t132 - t133, costab16) << 1) - t134; + + t151 = (t169 << 1) - t135; + + /* 22 */ lo[ 6][slot] = SHIFT(t151); + + t170 = (((MUL(t148 - t149, costab16) << 1) - t150) << 1) - t151; + + /* 26 */ lo[10][slot] = SHIFT(t170); + /* 30 */ lo[14][slot] = + SHIFT((((((MUL(t166 - t167, costab16) << 1) - + t168) << 1) - t169) << 1) - t170); + + t171 = MUL(t106 - t107, costab8); + t172 = MUL(t108 - t109, costab24); + t173 = t171 + t172; + + t138 = (t173 << 1) - t110; + + t123 = (t138 << 1) - t111; + + t139 = (MUL(t121 - t122, costab16) << 1) - t123; + + t117 = (t123 << 1) - t112; + + /* 15 */ hi[ 0][slot] = SHIFT(t117); + + t124 = (MUL(t115 - t116, costab16) << 1) - t117; + + /* 17 */ lo[ 1][slot] = SHIFT(t124); + + t131 = (t139 << 1) - t124; + + /* 19 */ lo[ 3][slot] = SHIFT(t131); + + t140 = (t164 << 1) - t131; + + /* 21 */ lo[ 5][slot] = SHIFT(t140); + + t174 = (MUL(t136 - t137, costab16) << 1) - t138; + + t155 = (t174 << 1) - t139; + + t147 = (t155 << 1) - t140; + + /* 23 */ lo[ 7][slot] = SHIFT(t147); + + t156 = (((MUL(t144 - t145, costab16) << 1) - t146) << 1) - t147; + + /* 25 */ lo[ 9][slot] = SHIFT(t156); + + t175 = (((MUL(t152 - t153, costab16) << 1) - t154) << 1) - t155; + + t165 = (t175 << 1) - t156; + + /* 27 */ lo[11][slot] = SHIFT(t165); + + t176 = (((((MUL(t161 - t162, costab16) << 1) - + t163) << 1) - t164) << 1) - t165; + + /* 29 */ lo[13][slot] = SHIFT(t176); + /* 31 */ lo[15][slot] = + SHIFT((((((((MUL(t171 - t172, costab16) << 1) - + t173) << 1) - t174) << 1) - t175) << 1) - t176); + + /* + * Totals: + * 80 multiplies + * 80 additions + * 119 subtractions + * 49 shifts (not counting SSO) + */ +} + +# undef MUL +# undef SHIFT + +/* third SSO shift and/or D[] optimization preshift */ + +# if defined(OPT_SSO) +# if MAD_F_FRACBITS != 28 +# error "MAD_F_FRACBITS must be 28 to use OPT_SSO" +# endif +# define ML0(hi, lo, x, y) ((lo) = (x) * (y)) +# define MLA(hi, lo, x, y) ((lo) += (x) * (y)) +# define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) +# define SHIFT(x) ((x) >> 2) +# define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14) +# else +# define ML0(hi, lo, x, y) MAD_F_ML0((hi), (lo), (x), (y)) +# define MLA(hi, lo, x, y) MAD_F_MLA((hi), (lo), (x), (y)) +# define MLZ(hi, lo) MAD_F_MLZ((hi), (lo)) +# define SHIFT(x) (x) +# if defined(MAD_F_SCALEBITS) +# undef MAD_F_SCALEBITS +# define MAD_F_SCALEBITS (MAD_F_FRACBITS - 12) +# define PRESHIFT(x) (MAD_F(x) >> 12) +# else +# define PRESHIFT(x) MAD_F(x) +# endif +# endif + +static +mad_fixed_t const D[17][32] = { +# include "D.dat" +}; + +# if defined(ASO_SYNTH) +void synth_full(struct mad_synth *, struct mad_frame const *, + unsigned int, unsigned int); +# else +/* + * NAME: synth->full() + * DESCRIPTION: perform full frequency PCM synthesis + */ +static +void synth_full(struct mad_synth *synth, struct mad_frame const *frame, + unsigned int nch, unsigned int ns) +{ + unsigned int phase, ch, s, sb, pe, po; + mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8]; + mad_fixed_t const (*sbsample)[36][32]; + register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; + register mad_fixed_t const (*Dptr)[32], *ptr; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + + for (ch = 0; ch < nch; ++ch) { + sbsample = &frame->sbsample[ch]; + filter = &synth->filter[ch]; + phase = synth->phase; + pcm1 = synth->pcm.samples[ch]; + + for (s = 0; s < ns; ++s) { + dct32((*sbsample)[s], phase >> 1, + (*filter)[0][phase & 1], (*filter)[1][phase & 1]); + + pe = phase & ~1; + po = ((phase - 1) & 0xf) | 1; + + /* calculate 32 samples */ + + fe = &(*filter)[0][ phase & 1][0]; + fx = &(*filter)[0][~phase & 1][0]; + fo = &(*filter)[1][~phase & 1][0]; + + Dptr = &D[0]; + + ptr = *Dptr + pe; + ML0(hi, lo, (*fe)[0], ptr[ 0]); + MLA(hi, lo, (*fe)[1], ptr[14]); + MLA(hi, lo, (*fe)[2], ptr[12]); + MLA(hi, lo, (*fe)[3], ptr[10]); + MLA(hi, lo, (*fe)[4], ptr[ 8]); + MLA(hi, lo, (*fe)[5], ptr[ 6]); + MLA(hi, lo, (*fe)[6], ptr[ 4]); + MLA(hi, lo, (*fe)[7], ptr[ 2]); + + ptr = *Dptr + po; + MLA(hi, lo, (*fx)[0], -ptr[ 0]); + MLA(hi, lo, (*fx)[1], -ptr[14]); + MLA(hi, lo, (*fx)[2], -ptr[12]); + MLA(hi, lo, (*fx)[3], -ptr[10]); + MLA(hi, lo, (*fx)[4], -ptr[ 8]); + MLA(hi, lo, (*fx)[5], -ptr[ 6]); + MLA(hi, lo, (*fx)[6], -ptr[ 4]); + MLA(hi, lo, (*fx)[7], -ptr[ 2]); + + *pcm1++ = SHIFT(MLZ(hi, lo)); + + pcm2 = pcm1 + 30; + + for (sb = 1; sb < 16; ++sb) { + ++fe; + ++Dptr; + + /* D[32 - sb][i] == -D[sb][31 - i] */ + + ptr = *Dptr + pe; + ML0(hi, lo, (*fe)[7], ptr[ 2]); + MLA(hi, lo, (*fe)[6], ptr[ 4]); + MLA(hi, lo, (*fe)[5], ptr[ 6]); + MLA(hi, lo, (*fe)[4], ptr[ 8]); + MLA(hi, lo, (*fe)[3], ptr[10]); + MLA(hi, lo, (*fe)[2], ptr[12]); + MLA(hi, lo, (*fe)[1], ptr[14]); + MLA(hi, lo, (*fe)[0], ptr[ 0]); + + ptr = *Dptr + po; + MLA(hi, lo, (*fo)[0], -ptr[ 0]); + MLA(hi, lo, (*fo)[1], -ptr[14]); + MLA(hi, lo, (*fo)[2], -ptr[12]); + MLA(hi, lo, (*fo)[3], -ptr[10]); + MLA(hi, lo, (*fo)[4], -ptr[ 8]); + MLA(hi, lo, (*fo)[5], -ptr[ 6]); + MLA(hi, lo, (*fo)[6], -ptr[ 4]); + MLA(hi, lo, (*fo)[7], -ptr[ 2]); + + *pcm1++ = SHIFT(MLZ(hi, lo)); + + ptr = *Dptr - po; + ML0(hi, lo, (*fo)[7], ptr[31 - 2]); + MLA(hi, lo, (*fo)[6], ptr[31 - 4]); + MLA(hi, lo, (*fo)[5], ptr[31 - 6]); + MLA(hi, lo, (*fo)[4], ptr[31 - 8]); + MLA(hi, lo, (*fo)[3], ptr[31 - 10]); + MLA(hi, lo, (*fo)[2], ptr[31 - 12]); + MLA(hi, lo, (*fo)[1], ptr[31 - 14]); + MLA(hi, lo, (*fo)[0], ptr[31 - 16]); + + ptr = *Dptr - pe; + MLA(hi, lo, (*fe)[0], ptr[31 - 16]); + MLA(hi, lo, (*fe)[1], ptr[31 - 14]); + MLA(hi, lo, (*fe)[2], ptr[31 - 12]); + MLA(hi, lo, (*fe)[3], ptr[31 - 10]); + MLA(hi, lo, (*fe)[4], ptr[31 - 8]); + MLA(hi, lo, (*fe)[5], ptr[31 - 6]); + MLA(hi, lo, (*fe)[6], ptr[31 - 4]); + MLA(hi, lo, (*fe)[7], ptr[31 - 2]); + + *pcm2-- = SHIFT(MLZ(hi, lo)); + + ++fo; + } + + ++Dptr; + + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + + *pcm1 = SHIFT(-MLZ(hi, lo)); + pcm1 += 16; + + phase = (phase + 1) % 16; + } + } +} +# endif + +/* + * NAME: synth->half() + * DESCRIPTION: perform half frequency PCM synthesis + */ +static +void synth_half(struct mad_synth *synth, struct mad_frame const *frame, + unsigned int nch, unsigned int ns) +{ + unsigned int phase, ch, s, sb, pe, po; + mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8]; + mad_fixed_t const (*sbsample)[36][32]; + register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; + register mad_fixed_t const (*Dptr)[32], *ptr; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + + for (ch = 0; ch < nch; ++ch) { + sbsample = &frame->sbsample[ch]; + filter = &synth->filter[ch]; + phase = synth->phase; + pcm1 = synth->pcm.samples[ch]; + + for (s = 0; s < ns; ++s) { + dct32((*sbsample)[s], phase >> 1, + (*filter)[0][phase & 1], (*filter)[1][phase & 1]); + + pe = phase & ~1; + po = ((phase - 1) & 0xf) | 1; + + /* calculate 16 samples */ + + fe = &(*filter)[0][ phase & 1][0]; + fx = &(*filter)[0][~phase & 1][0]; + fo = &(*filter)[1][~phase & 1][0]; + + Dptr = &D[0]; + + ptr = *Dptr + pe; + ML0(hi, lo, (*fe)[0], ptr[ 0]); + MLA(hi, lo, (*fe)[1], ptr[14]); + MLA(hi, lo, (*fe)[2], ptr[12]); + MLA(hi, lo, (*fe)[3], ptr[10]); + MLA(hi, lo, (*fe)[4], ptr[ 8]); + MLA(hi, lo, (*fe)[5], ptr[ 6]); + MLA(hi, lo, (*fe)[6], ptr[ 4]); + MLA(hi, lo, (*fe)[7], ptr[ 2]); + + ptr = *Dptr + po; + MLA(hi, lo, (*fx)[0], -ptr[ 0]); + MLA(hi, lo, (*fx)[1], -ptr[14]); + MLA(hi, lo, (*fx)[2], -ptr[12]); + MLA(hi, lo, (*fx)[3], -ptr[10]); + MLA(hi, lo, (*fx)[4], -ptr[ 8]); + MLA(hi, lo, (*fx)[5], -ptr[ 6]); + MLA(hi, lo, (*fx)[6], -ptr[ 4]); + MLA(hi, lo, (*fx)[7], -ptr[ 2]); + + *pcm1++ = SHIFT(MLZ(hi, lo)); + + pcm2 = pcm1 + 14; + + for (sb = 1; sb < 16; ++sb) { + ++fe; + ++Dptr; + + /* D[32 - sb][i] == -D[sb][31 - i] */ + + if (!(sb & 1)) { + ptr = *Dptr + pe; + ML0(hi, lo, (*fe)[7], ptr[ 2]); + MLA(hi, lo, (*fe)[6], ptr[ 4]); + MLA(hi, lo, (*fe)[5], ptr[ 6]); + MLA(hi, lo, (*fe)[4], ptr[ 8]); + MLA(hi, lo, (*fe)[3], ptr[10]); + MLA(hi, lo, (*fe)[2], ptr[12]); + MLA(hi, lo, (*fe)[1], ptr[14]); + MLA(hi, lo, (*fe)[0], ptr[ 0]); + + ptr = *Dptr + po; + MLA(hi, lo, (*fo)[0], -ptr[ 0]); + MLA(hi, lo, (*fo)[1], -ptr[14]); + MLA(hi, lo, (*fo)[2], -ptr[12]); + MLA(hi, lo, (*fo)[3], -ptr[10]); + MLA(hi, lo, (*fo)[4], -ptr[ 8]); + MLA(hi, lo, (*fo)[5], -ptr[ 6]); + MLA(hi, lo, (*fo)[6], -ptr[ 4]); + MLA(hi, lo, (*fo)[7], -ptr[ 2]); + + *pcm1++ = SHIFT(MLZ(hi, lo)); + + ptr = *Dptr - po; + ML0(hi, lo, (*fo)[7], ptr[31 - 2]); + MLA(hi, lo, (*fo)[6], ptr[31 - 4]); + MLA(hi, lo, (*fo)[5], ptr[31 - 6]); + MLA(hi, lo, (*fo)[4], ptr[31 - 8]); + MLA(hi, lo, (*fo)[3], ptr[31 - 10]); + MLA(hi, lo, (*fo)[2], ptr[31 - 12]); + MLA(hi, lo, (*fo)[1], ptr[31 - 14]); + MLA(hi, lo, (*fo)[0], ptr[31 - 16]); + + ptr = *Dptr - pe; + MLA(hi, lo, (*fe)[0], ptr[31 - 16]); + MLA(hi, lo, (*fe)[1], ptr[31 - 14]); + MLA(hi, lo, (*fe)[2], ptr[31 - 12]); + MLA(hi, lo, (*fe)[3], ptr[31 - 10]); + MLA(hi, lo, (*fe)[4], ptr[31 - 8]); + MLA(hi, lo, (*fe)[5], ptr[31 - 6]); + MLA(hi, lo, (*fe)[6], ptr[31 - 4]); + MLA(hi, lo, (*fe)[7], ptr[31 - 2]); + + *pcm2-- = SHIFT(MLZ(hi, lo)); + } + + ++fo; + } + + ++Dptr; + + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + + *pcm1 = SHIFT(-MLZ(hi, lo)); + pcm1 += 8; + + phase = (phase + 1) % 16; + } + } +} + +/* + * NAME: synth->frame() + * DESCRIPTION: perform PCM synthesis of frame subband samples + */ +void mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame) +{ + unsigned int nch, ns; + void (*synth_frame)(struct mad_synth *, struct mad_frame const *, + unsigned int, unsigned int); + + nch = MAD_NCHANNELS(&frame->header); + ns = MAD_NSBSAMPLES(&frame->header); + + synth->pcm.samplerate = frame->header.samplerate; + synth->pcm.channels = nch; + synth->pcm.length = 32 * ns; + + synth_frame = synth_full; + + if (frame->options & MAD_OPTION_HALFSAMPLERATE) { + synth->pcm.samplerate /= 2; + synth->pcm.length /= 2; + + synth_frame = synth_half; + } + + synth_frame(synth, frame, nch, ns); + + synth->phase = (synth->phase + ns) % 16; +} diff --git a/core/multimedia/opieplayer/libmad/synth.h b/core/multimedia/opieplayer/libmad/synth.h new file mode 100644 index 0000000..64f6a86 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/synth.h @@ -0,0 +1,50 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_SYNTH_H +# define LIBMAD_SYNTH_H + +# include "fixed.h" +# include "frame.h" + +struct mad_synth { + mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ + /* [ch][eo][peo][s][v] */ + + unsigned int phase; /* current processing phase */ + + struct mad_pcm { + unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short channels; /* number of channels */ + unsigned short length; /* number of samples per channel */ + mad_fixed_t samples[2][1152]; /* PCM output samples */ + } pcm; +}; + +void mad_synth_init(struct mad_synth *); + +# define mad_synth_finish(synth) /* nothing */ + +void mad_synth_mute(struct mad_synth *); + +void mad_synth_frame(struct mad_synth *, struct mad_frame const *); + +# endif diff --git a/core/multimedia/opieplayer/libmad/timer.c b/core/multimedia/opieplayer/libmad/timer.c new file mode 100644 index 0000000..b30680c --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/timer.c @@ -0,0 +1,480 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# include +# include + +# include "timer.h" + +mad_timer_t const mad_timer_zero = { 0, 0 }; + +/* + * NAME: timer->compare() + * DESCRIPTION: indicate relative order of two timers + */ +int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2) +{ + signed long diff; + + diff = timer1.seconds - timer2.seconds; + if (diff < 0) + return -1; + else if (diff > 0) + return +1; + + diff = timer1.fraction - timer2.fraction; + if (diff < 0) + return -1; + else if (diff > 0) + return +1; + + return 0; +} + +/* + * NAME: timer->negate() + * DESCRIPTION: invert the sign of a timer + */ +void mad_timer_negate(mad_timer_t *timer) +{ + timer->seconds = -timer->seconds; + + if (timer->fraction) { + timer->seconds -= 1; + timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction; + } +} + +/* + * NAME: timer->abs() + * DESCRIPTION: return the absolute value of a timer + */ +mad_timer_t mad_timer_abs(mad_timer_t timer) +{ + if (mad_timer_sign(timer) < 0) + mad_timer_negate(&timer); + + return timer; +} + +/* + * NAME: reduce_timer() + * DESCRIPTION: carry timer fraction into seconds + */ +static +void reduce_timer(mad_timer_t *timer) +{ + timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION; + timer->fraction %= MAD_TIMER_RESOLUTION; +} + +/* + * NAME: gcd() + * DESCRIPTION: compute greatest common denominator + */ +static +unsigned long gcd(unsigned long num1, unsigned long num2) +{ + unsigned long tmp; + + while (num2) { + tmp = num2; + num2 = num1 % num2; + num1 = tmp; + } + + return num1; +} + +/* + * NAME: reduce_rational() + * DESCRIPTION: convert rational expression to lowest terms + */ +static +void reduce_rational(unsigned long *numer, unsigned long *denom) +{ + unsigned long factor; + + factor = gcd(*numer, *denom); + + assert(factor != 0); + + *numer /= factor; + *denom /= factor; +} + +/* + * NAME: scale_rational() + * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing + */ +static +unsigned long scale_rational(unsigned long numer, unsigned long denom, + unsigned long scale) +{ + reduce_rational(&numer, &denom); + reduce_rational(&scale, &denom); + + assert(denom != 0); + + if (denom < scale) + return numer * (scale / denom) + numer * (scale % denom) / denom; + if (denom < numer) + return scale * (numer / denom) + scale * (numer % denom) / denom; + + return numer * scale / denom; +} + +/* + * NAME: timer->set() + * DESCRIPTION: set timer to specific value + */ +void mad_timer_set(mad_timer_t *timer, unsigned long seconds, + unsigned long fraction, unsigned long fracparts) +{ + timer->seconds = seconds; + + if (fraction == 0) + fracparts = 0; + else if (fracparts == 0) { + fracparts = fraction; + fraction = 1; + } + + switch (fracparts) { + case 0: + timer->fraction = 0; + break; + + case MAD_TIMER_RESOLUTION: + timer->fraction = fraction; + break; + + case 8000: + timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 8000); + break; + + case 11025: + timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 11025); + break; + + case 12000: + timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 12000); + break; + + case 16000: + timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 16000); + break; + + case 22050: + timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 22050); + break; + + case 24000: + timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 24000); + break; + + case 32000: + timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 32000); + break; + + case 44100: + timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 44100); + break; + + case 48000: + timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 48000); + break; + + default: + timer->fraction = + scale_rational(fraction, fracparts, MAD_TIMER_RESOLUTION); + break; + } + + if (timer->fraction >= MAD_TIMER_RESOLUTION) + reduce_timer(timer); +} + +/* + * NAME: timer->add() + * DESCRIPTION: add one timer to another + */ +void mad_timer_add(mad_timer_t *timer, mad_timer_t incr) +{ + timer->seconds += incr.seconds; + timer->fraction += incr.fraction; + + if (timer->fraction >= MAD_TIMER_RESOLUTION) + reduce_timer(timer); +} + +/* + * NAME: timer->multiply() + * DESCRIPTION: multiply a timer by a scalar value + */ +void mad_timer_multiply(mad_timer_t *timer, signed long scalar) +{ + mad_timer_t addend; + unsigned long factor; + + factor = scalar; + if (scalar < 0) { + mad_timer_negate(timer); + factor = -scalar; + } + + addend = *timer; + *timer = mad_timer_zero; + + while (factor) { + if (factor & 1) + mad_timer_add(timer, addend); + + mad_timer_add(&addend, addend); + factor >>= 1; + } +} + +/* + * NAME: timer->count() + * DESCRIPTION: return timer value in selected units + */ +signed long mad_timer_count(mad_timer_t timer, enum mad_units units) +{ + switch (units) { + case MAD_UNITS_HOURS: + return timer.seconds / 60 / 60; + + case MAD_UNITS_MINUTES: + return timer.seconds / 60; + + case MAD_UNITS_SECONDS: + return timer.seconds; + + case MAD_UNITS_DECISECONDS: + case MAD_UNITS_CENTISECONDS: + case MAD_UNITS_MILLISECONDS: + + case MAD_UNITS_8000_HZ: + case MAD_UNITS_11025_HZ: + case MAD_UNITS_12000_HZ: + case MAD_UNITS_16000_HZ: + case MAD_UNITS_22050_HZ: + case MAD_UNITS_24000_HZ: + case MAD_UNITS_32000_HZ: + case MAD_UNITS_44100_HZ: + case MAD_UNITS_48000_HZ: + + case MAD_UNITS_24_FPS: + case MAD_UNITS_25_FPS: + case MAD_UNITS_30_FPS: + case MAD_UNITS_48_FPS: + case MAD_UNITS_50_FPS: + case MAD_UNITS_60_FPS: + case MAD_UNITS_75_FPS: + return timer.seconds * (signed long) units + + (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, + units); + + case MAD_UNITS_23_976_FPS: + case MAD_UNITS_24_975_FPS: + case MAD_UNITS_29_97_FPS: + case MAD_UNITS_47_952_FPS: + case MAD_UNITS_49_95_FPS: + case MAD_UNITS_59_94_FPS: + return (mad_timer_count(timer, -units) + 1) * 1000 / 1001; + } + + /* unsupported units */ + return 0; +} + +/* + * NAME: timer->fraction() + * DESCRIPTION: return fractional part of timer in arbitrary terms + */ +unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long fracparts) +{ + timer = mad_timer_abs(timer); + + switch (fracparts) { + case 0: + return MAD_TIMER_RESOLUTION / timer.fraction; + + case MAD_TIMER_RESOLUTION: + return timer.fraction; + + default: + return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, fracparts); + } +} + +/* + * NAME: timer->string() + * DESCRIPTION: write a string representation of a timer using a template + */ +void mad_timer_string(mad_timer_t timer, + char *dest, char const *format, enum mad_units units, + enum mad_units fracunits, unsigned long subparts) +{ + unsigned long hours, minutes, seconds, sub; + unsigned int frac; + + timer = mad_timer_abs(timer); + + seconds = timer.seconds; + frac = sub = 0; + + switch (fracunits) { + case MAD_UNITS_HOURS: + case MAD_UNITS_MINUTES: + case MAD_UNITS_SECONDS: + break; + + case MAD_UNITS_DECISECONDS: + case MAD_UNITS_CENTISECONDS: + case MAD_UNITS_MILLISECONDS: + + case MAD_UNITS_8000_HZ: + case MAD_UNITS_11025_HZ: + case MAD_UNITS_12000_HZ: + case MAD_UNITS_16000_HZ: + case MAD_UNITS_22050_HZ: + case MAD_UNITS_24000_HZ: + case MAD_UNITS_32000_HZ: + case MAD_UNITS_44100_HZ: + case MAD_UNITS_48000_HZ: + + case MAD_UNITS_24_FPS: + case MAD_UNITS_25_FPS: + case MAD_UNITS_30_FPS: + case MAD_UNITS_48_FPS: + case MAD_UNITS_50_FPS: + case MAD_UNITS_60_FPS: + case MAD_UNITS_75_FPS: + { + unsigned long fracparts; + + fracparts = MAD_TIMER_RESOLUTION / fracunits; + + frac = timer.fraction / fracparts; + sub = scale_rational(timer.fraction % fracparts, fracparts, subparts); + } + break; + + case MAD_UNITS_23_976_FPS: + case MAD_UNITS_24_975_FPS: + case MAD_UNITS_29_97_FPS: + case MAD_UNITS_47_952_FPS: + case MAD_UNITS_49_95_FPS: + case MAD_UNITS_59_94_FPS: + /* drop-frame encoding */ + /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */ + { + unsigned long frame, cycle, d, m; + + frame = mad_timer_count(timer, fracunits); + + cycle = -fracunits * 60 * 10 - (10 - 1) * 2; + + d = frame / cycle; + m = frame % cycle; + frame += (10 - 1) * 2 * d; + if (m > 2) + frame += 2 * ((m - 2) / (cycle / 10)); + + frac = frame % -fracunits; + seconds = frame / -fracunits; + } + break; + } + + switch (units) { + case MAD_UNITS_HOURS: + minutes = seconds / 60; + hours = minutes / 60; + + sprintf(dest, format, + hours, + (unsigned int) (minutes % 60), + (unsigned int) (seconds % 60), + frac, sub); + break; + + case MAD_UNITS_MINUTES: + minutes = seconds / 60; + + sprintf(dest, format, + minutes, + (unsigned int) (seconds % 60), + frac, sub); + break; + + case MAD_UNITS_SECONDS: + sprintf(dest, format, + seconds, + frac, sub); + break; + + case MAD_UNITS_23_976_FPS: + case MAD_UNITS_24_975_FPS: + case MAD_UNITS_29_97_FPS: + case MAD_UNITS_47_952_FPS: + case MAD_UNITS_49_95_FPS: + case MAD_UNITS_59_94_FPS: + if (fracunits < 0) { + /* not yet implemented */ + sub = 0; + } + + /* fall through */ + + case MAD_UNITS_DECISECONDS: + case MAD_UNITS_CENTISECONDS: + case MAD_UNITS_MILLISECONDS: + + case MAD_UNITS_8000_HZ: + case MAD_UNITS_11025_HZ: + case MAD_UNITS_12000_HZ: + case MAD_UNITS_16000_HZ: + case MAD_UNITS_22050_HZ: + case MAD_UNITS_24000_HZ: + case MAD_UNITS_32000_HZ: + case MAD_UNITS_44100_HZ: + case MAD_UNITS_48000_HZ: + + case MAD_UNITS_24_FPS: + case MAD_UNITS_25_FPS: + case MAD_UNITS_30_FPS: + case MAD_UNITS_48_FPS: + case MAD_UNITS_50_FPS: + case MAD_UNITS_60_FPS: + case MAD_UNITS_75_FPS: + sprintf(dest, format, mad_timer_count(timer, units), sub); + break; + } +} diff --git a/core/multimedia/opieplayer/libmad/timer.h b/core/multimedia/opieplayer/libmad/timer.h new file mode 100644 index 0000000..67fe16a --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/timer.h @@ -0,0 +1,100 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifndef LIBMAD_TIMER_H +# define LIBMAD_TIMER_H + +typedef struct { + signed long seconds; /* whole seconds */ + unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ +} mad_timer_t; + +extern mad_timer_t const mad_timer_zero; + +# define MAD_TIMER_RESOLUTION 352800000UL + +enum mad_units { + MAD_UNITS_HOURS = -2, + MAD_UNITS_MINUTES = -1, + MAD_UNITS_SECONDS = 0, + + /* metric units */ + + MAD_UNITS_DECISECONDS = 10, + MAD_UNITS_CENTISECONDS = 100, + MAD_UNITS_MILLISECONDS = 1000, + + /* audio sample units */ + + MAD_UNITS_8000_HZ = 8000, + MAD_UNITS_11025_HZ = 11025, + MAD_UNITS_12000_HZ = 12000, + + MAD_UNITS_16000_HZ = 16000, + MAD_UNITS_22050_HZ = 22050, + MAD_UNITS_24000_HZ = 24000, + + MAD_UNITS_32000_HZ = 32000, + MAD_UNITS_44100_HZ = 44100, + MAD_UNITS_48000_HZ = 48000, + + /* video frame/field units */ + + MAD_UNITS_24_FPS = 24, + MAD_UNITS_25_FPS = 25, + MAD_UNITS_30_FPS = 30, + MAD_UNITS_48_FPS = 48, + MAD_UNITS_50_FPS = 50, + MAD_UNITS_60_FPS = 60, + + /* CD audio frames */ + + MAD_UNITS_75_FPS = 75, + + /* video drop-frame units */ + + MAD_UNITS_23_976_FPS = -24, + MAD_UNITS_24_975_FPS = -25, + MAD_UNITS_29_97_FPS = -30, + MAD_UNITS_47_952_FPS = -48, + MAD_UNITS_49_95_FPS = -50, + MAD_UNITS_59_94_FPS = -60 +}; + +# define mad_timer_reset(timer) (*(timer) = mad_timer_zero) + +int mad_timer_compare(mad_timer_t, mad_timer_t); + +# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero) + +void mad_timer_negate(mad_timer_t *); +mad_timer_t mad_timer_abs(mad_timer_t); + +void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long); +void mad_timer_add(mad_timer_t *, mad_timer_t); +void mad_timer_multiply(mad_timer_t *, signed long); + +signed long mad_timer_count(mad_timer_t, enum mad_units); +unsigned long mad_timer_fraction(mad_timer_t, unsigned long); +void mad_timer_string(mad_timer_t, char *, char const *, + enum mad_units, enum mad_units, unsigned long); + +# endif diff --git a/core/multimedia/opieplayer/libmad/version.c b/core/multimedia/opieplayer/libmad/version.c new file mode 100644 index 0000000..413d54b --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/version.c @@ -0,0 +1,91 @@ +/* + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +# ifdef HAVE_CONFIG_H +# include "libmad_config.h" +# endif + +# include "libmad_global.h" + +# include "libmad_version.h" + +char const mad_version[] = "MPEG Audio Decoder version " MAD_VERSION; +char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR; +char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">"; + +char const mad_build[] = +# if defined(FPM_64BIT) + "FPM_64BIT " +# elif defined(FPM_INTEL) + "FPM_INTEL " +# elif defined(FPM_ARM) + "FPM_ARM " +# elif defined(FPM_MIPS) + "FPM_MIPS " +# elif defined(FPM_SPARC) + "FPM_SPARC " +# elif defined(FPM_PPC) + "FPM_PPC " +# elif defined(FPM_DEFAULT) + "FPM_DEFAULT " +# endif + +# if defined(ASO_IMDCT) + "ASO_IMDCT " +# endif +# if defined(ASO_INTERLEAVE1) + "ASO_INTERLEAVE1 " +# endif +# if defined(ASO_INTERLEAVE2) + "ASO_INTERLEAVE2 " +# endif +# if defined(ASO_ZEROCHECK) + "ASO_ZEROCHECK " +# endif + +# if defined(OPT_SPEED) + "OPT_SPEED " +# elif defined(OPT_ACCURACY) + "OPT_ACCURACY " +# endif + +# if defined(OPT_SSO) + "OPT_SSO " +# endif + +# if defined(OPT_DCTO) /* never defined here */ + "OPT_DCTO " +# endif + +# if defined(OPT_STRICT) + "OPT_STRICT " +# endif + +# if defined(EXPERIMENTAL) + "EXPERIMENTAL " +# endif + +# if defined(DEBUG) + "DEBUG " +# elif defined(NDEBUG) + "NDEBUG " +# endif +; diff --git a/core/multimedia/opieplayer/libmpeg3/.cvsignore b/core/multimedia/opieplayer/libmpeg3/.cvsignore new file mode 100644 index 0000000..d7bb3c1 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/.cvsignore @@ -0,0 +1,5 @@ +global_config +dump +mpeg3toc +mpeg3cat +Makefile diff --git a/core/multimedia/opieplayer/libmpeg3/COPYING b/core/multimedia/opieplayer/libmpeg3/COPYING new file mode 100644 index 0000000..60549be --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/core/multimedia/opieplayer/libmpeg3/Makefile.in b/core/multimedia/opieplayer/libmpeg3/Makefile.in new file mode 100644 index 0000000..1817902 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/Makefile.in @@ -0,0 +1,774 @@ +############################################################################# + +####### Compiler, tools and options + +CXX = $(SYSCONF_CXX) $(QT_CXX_MT) +CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) -DQCONFIG=\"qpe\" +CC = $(SYSCONF_CC) $(QT_C_MT) +CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) -DQCONFIG=\"qpe\" +INCPATH = -I$(QPEDIR)/include -I.. +LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) +LIBS = $(SUBLIBS) -lqpe -lpthread -lm $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP) +MOC = $(SYSCONF_MOC) +UIC = $(SYSCONF_UIC) + +####### Target + +DESTDIR = ../../plugins/codecs/ +VER_MAJ = 1 +VER_MIN = 0 +VER_PATCH = 0 +TARGET = mpeg3plugin +TARGET1 = lib$(TARGET).so.$(VER_MAJ) + +####### Files + +HEADERS = libmpeg3plugin.h \ + libmpeg3pluginimpl.h +SOURCES = libmpeg3plugin.cpp \ + libmpeg3pluginimpl.cpp \ + bitstream.c \ + libmpeg3.c \ + mpeg3atrack.c \ + mpeg3css.c \ + mpeg3demux.c \ + mpeg3io.c \ + mpeg3title.c \ + mpeg3vtrack.c \ + audio/ac3.c \ + audio/bit_allocation.c \ + audio/dct.c \ + audio/exponents.c \ + audio/header.c \ + audio/layer2.c \ + audio/layer3.c \ + audio/mantissa.c \ + audio/mpeg3audio.c \ + audio/pcm.c \ + audio/synthesizers.c \ + audio/tables.c \ + video/getpicture.c \ + video/headers.c \ + video/idct.c \ + video/macroblocks.c \ + video/mmxtest.c \ + video/motion.c \ + video/mpeg3video.c \ + video/output.c \ + video/reconstruct.c \ + video/seek.c \ + video/slice.c \ + video/vlc.c +OBJECTS = libmpeg3plugin.o \ + libmpeg3pluginimpl.o \ + bitstream.o \ + libmpeg3.o \ + mpeg3atrack.o \ + mpeg3css.o \ + mpeg3demux.o \ + mpeg3io.o \ + mpeg3title.o \ + mpeg3vtrack.o \ + audio/ac3.o \ + audio/bit_allocation.o \ + audio/dct.o \ + audio/exponents.o \ + audio/header.o \ + audio/layer2.o \ + audio/layer3.o \ + audio/mantissa.o \ + audio/mpeg3audio.o \ + audio/pcm.o \ + audio/synthesizers.o \ + audio/tables.o \ + video/getpicture.o \ + video/headers.o \ + video/idct.o \ + video/macroblocks.o \ + video/mmxtest.o \ + video/motion.o \ + video/mpeg3video.o \ + video/output.o \ + video/reconstruct.o \ + video/seek.o \ + video/slice.o \ + video/vlc.o +INTERFACES = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = + + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + + +all: $(DESTDIR)$(SYSCONF_LINK_TARGET) + +$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) + $(SYSCONF_LINK_LIB) + +moc: $(SRCMOC) + +tmake: + tmake libmpeg3.pro + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) + -rm -f *~ core + -rm -f allmoc.cpp + +####### Extension Modules + +listpromodules: + @echo + +listallmodules: + @echo + +listaddonpromodules: + @echo + +listaddonentmodules: + @echo + + +REQUIRES= + +####### Sub-libraries + + +###### Combined headers + + + +####### Compile + +libmpeg3plugin.o: libmpeg3plugin.cpp \ + libmpeg3plugin.h \ + libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + mpeg3protos.h \ + ../mediaplayerplugininterface.h + +libmpeg3pluginimpl.o: libmpeg3pluginimpl.cpp \ + libmpeg3plugin.h \ + libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + mpeg3protos.h \ + ../mediaplayerplugininterface.h \ + libmpeg3pluginimpl.h \ + ../mediaplayerplugininterface.h + +bitstream.o: bitstream.c \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + mpeg3protos.h + +libmpeg3.o: libmpeg3.c \ + libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + mpeg3protos.h + +mpeg3atrack.o: mpeg3atrack.c \ + libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + mpeg3protos.h + +mpeg3css.o: mpeg3css.c \ + mpeg3css.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h + +mpeg3demux.o: mpeg3demux.c \ + libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + mpeg3protos.h + +mpeg3io.o: mpeg3io.c \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + mpeg3protos.h + +mpeg3title.o: mpeg3title.c \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + mpeg3protos.h + +mpeg3vtrack.o: mpeg3vtrack.c \ + libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + mpeg3protos.h + +audio/ac3.o: audio/ac3.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h + +audio/bit_allocation.o: audio/bit_allocation.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h + +audio/dct.o: audio/dct.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h \ + audio/tables.h \ + audio/fptables.h + +audio/exponents.o: audio/exponents.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h + +audio/header.o: audio/header.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/tables.h \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h + +audio/layer2.o: audio/layer2.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h \ + audio/tables.h + +audio/layer3.o: audio/layer3.c \ + audio/huffman.h \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h \ + audio/tables.h + +audio/mantissa.o: audio/mantissa.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h + +audio/mpeg3audio.o: audio/mpeg3audio.c \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h \ + audio/mpeg3audio.h \ + audio/tables.h + +audio/pcm.o: audio/pcm.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h + +audio/synthesizers.o: audio/synthesizers.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h \ + audio/tables.h + +audio/tables.o: audio/tables.c \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + audio/../mpeg3protos.h \ + audio/tables.h \ + audio/fptables.h + +video/getpicture.o: video/getpicture.c \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/../mpeg3protos.h \ + video/mpeg3video.h \ + video/vlc.h + +video/headers.o: video/headers.c \ + video/../mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/../mpeg3protos.h \ + video/mpeg3video.h + +video/idct.o: video/idct.c \ + video/idct.h + +video/macroblocks.o: video/macroblocks.c \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/../mpeg3protos.h \ + video/mpeg3video.h \ + video/vlc.h + +video/mmxtest.o: video/mmxtest.c \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/../mpeg3protos.h + +video/motion.o: video/motion.c \ + video/mpeg3video.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3protos.h \ + video/vlc.h + +video/mpeg3video.o: video/mpeg3video.c \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/../mpeg3protos.h \ + video/mpeg3video.h \ + video/mpeg3videoprotos.h + +video/output.o: video/output.c \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/../mpeg3protos.h \ + video/mpeg3video.h + +video/reconstruct.o: video/reconstruct.c \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/../mpeg3protos.h \ + video/mpeg3video.h + +video/seek.o: video/seek.c \ + video/../mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/../mpeg3protos.h \ + video/mpeg3video.h + +video/slice.o: video/slice.c \ + audio/../libmpeg3.h \ + mpeg3private.h \ + mpeg3atrack.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + audio/mpeg3audio.h \ + audio/ac3.h \ + audio/mpeg3real.h \ + audio/../bitstream.h \ + mpeg3vtrack.h \ + video/mpeg3video.h \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/../mpeg3protos.h \ + video/mpeg3video.h \ + video/mpeg3videoprotos.h + +video/vlc.o: video/vlc.c \ + video/mpeg3video.h \ + audio/../bitstream.h \ + mpeg3demux.h \ + mpeg3title.h \ + mpeg3io.h \ + mpeg3css.h \ + mpeg3private.inc \ + video/../mpeg3private.inc \ + video/idct.h \ + video/slice.h \ + video/../timecode.h \ + video/vlc.h + + diff --git a/core/multimedia/opieplayer/libmpeg3/README b/core/multimedia/opieplayer/libmpeg3/README new file mode 100644 index 0000000..7a2a061 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/README @@ -0,0 +1,35 @@ +/******************************************************** + * LibMPEG3 + * Author: Adam Williams + * Page: heroine.linuxbox.com + * + * libmpeg3 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * libmpeg3 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + *******************************************************/ + + +/********************************************************** + * Credits: + *********************************************************/ + +AC3 decoder: + + Written by Aaron Holtzman (aholtzma@engr.uvic.ca) + + + +Problems: + + Streams where the multiplexing packet size changes at random. diff --git a/core/multimedia/opieplayer/libmpeg3/VERSION b/core/multimedia/opieplayer/libmpeg3/VERSION new file mode 100644 index 0000000..55772e2 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/VERSION @@ -0,0 +1 @@ +libmpeg3-1.2.1 diff --git a/core/multimedia/opieplayer/libmpeg3/audio/Makefile b/core/multimedia/opieplayer/libmpeg3/audio/Makefile new file mode 100644 index 0000000..eaa0e0b --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/Makefile @@ -0,0 +1,35 @@ +include ../global_config +export CFLAGS +export CFLAGS_lessopt + +OBJS = \ + ac3.o \ + bit_allocation.o \ + dct.o \ + exponents.o \ + header.o \ + layer2.o \ + layer3.o \ + mantissa.o \ + mpeg3audio.o \ + pcm.o \ + synthesizers.o \ + tables.o + +all: $(OBJS) + +dct.o: dct.c + $(CC) -c `./c_flags dct.c` -o $@ $< + +synthesizers.o: synthesizers.c + $(CC) -c `./c_flags synthesizers.c` -o $@ $< + + +.c.o: + $(CC) -c `./c_flags` -o $@ $< + +.s.o: + $(CC) -f elf $*.s + +clean: + rm -f *.o diff --git a/core/multimedia/opieplayer/libmpeg3/audio/ac3.c b/core/multimedia/opieplayer/libmpeg3/audio/ac3.c new file mode 100644 index 0000000..7a3b664 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/ac3.c @@ -0,0 +1,691 @@ +/* + * + * ac3.c Copyright (C) Aaron Holtzman - May 1999 + * + * + * This file is part of libmpeg3 + * + * libmpeg3 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * libmpeg3 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" + +#include +#include +#include +#include + +#define MPEG3AC3_MAGIC_NUMBER 0xdeadbeef + + +int mpeg3_ac3_samplerates[] = { 48000, 44100, 32000 }; + +struct mpeg3_framesize_s +{ + unsigned short bit_rate; + unsigned short frm_size[3]; +}; + +struct mpeg3_framesize_s framesize_codes[] = +{ + { 32 ,{64 ,69 ,96 } }, + { 32 ,{64 ,70 ,96 } }, + { 40 ,{80 ,87 ,120 } }, + { 40 ,{80 ,88 ,120 } }, + { 48 ,{96 ,104 ,144 } }, + { 48 ,{96 ,105 ,144 } }, + { 56 ,{112 ,121 ,168 } }, + { 56 ,{112 ,122 ,168 } }, + { 64 ,{128 ,139 ,192 } }, + { 64 ,{128 ,140 ,192 } }, + { 80 ,{160 ,174 ,240 } }, + { 80 ,{160 ,175 ,240 } }, + { 96 ,{192 ,208 ,288 } }, + { 96 ,{192 ,209 ,288 } }, + { 112 ,{224 ,243 ,336 } }, + { 112 ,{224 ,244 ,336 } }, + { 128 ,{256 ,278 ,384 } }, + { 128 ,{256 ,279 ,384 } }, + { 160 ,{320 ,348 ,480 } }, + { 160 ,{320 ,349 ,480 } }, + { 192 ,{384 ,417 ,576 } }, + { 192 ,{384 ,418 ,576 } }, + { 224 ,{448 ,487 ,672 } }, + { 224 ,{448 ,488 ,672 } }, + { 256 ,{512 ,557 ,768 } }, + { 256 ,{512 ,558 ,768 } }, + { 320 ,{640 ,696 ,960 } }, + { 320 ,{640 ,697 ,960 } }, + { 384 ,{768 ,835 ,1152 } }, + { 384 ,{768 ,836 ,1152 } }, + { 448 ,{896 ,975 ,1344 } }, + { 448 ,{896 ,976 ,1344 } }, + { 512 ,{1024 ,1114 ,1536 } }, + { 512 ,{1024 ,1115 ,1536 } }, + { 576 ,{1152 ,1253 ,1728 } }, + { 576 ,{1152 ,1254 ,1728 } }, + { 640 ,{1280 ,1393 ,1920 } }, + { 640 ,{1280 ,1394 ,1920 } } +}; + +/* Audio channel modes */ +short mpeg3_ac3_acmodes[] = {2, 1, 2, 3, 3, 4, 4, 5}; + +/* Rematrix tables */ +struct rematrix_band_s +{ + int start; + int end; +}; + +struct rematrix_band_s mpeg3_rematrix_band[] = +{ + {13, 24}, + {25, 36}, + {37, 60}, + {61, 252} +}; + +int mpeg3_min(int x, int y) +{ + return (x < y) ? x : y; +} + +int mpeg3_max(int x, int y) +{ + return (x > y) ? x : y; +} + +int mpeg3audio_read_ac3_header(mpeg3audio_t *audio) +{ + unsigned int code, crc; + unsigned int i; + mpeg3_ac3bsi_t *bsi = &(audio->ac3_bsi); + +/* Get the sync code */ + code = mpeg3bits_getbits(audio->astream, 16); + while(!mpeg3bits_eof(audio->astream) && code != MPEG3_AC3_START_CODE) + { + code <<= 8; + code &= 0xffff; + code |= mpeg3bits_getbits(audio->astream, 8); + } + + if(mpeg3bits_eof(audio->astream)) return 1; + +/* Get crc1 - we don't actually use this data though */ +/* The crc can be the same as the sync code or come after a sync code repeated twice */ + crc = mpeg3bits_getbits(audio->astream, 16); + +/* Got the sync code. Read the entire frame into a buffer if possible. */ + if(audio->avg_framesize > 0) + { + if(mpeg3bits_read_buffer(audio->astream, audio->ac3_buffer, audio->framesize - 4)) + return 1; + mpeg3bits_use_ptr(audio->astream, audio->ac3_buffer); + } + +/* Get the sampling rate code */ + audio->sampling_frequency_code = mpeg3bits_getbits(audio->astream, 2); + +/* Get the frame size code */ + audio->ac3_framesize_code = mpeg3bits_getbits(audio->astream, 6); + + audio->bitrate = framesize_codes[audio->ac3_framesize_code].bit_rate; + audio->avg_framesize = audio->framesize = 2 * framesize_codes[audio->ac3_framesize_code].frm_size[audio->sampling_frequency_code]; + +/* Check the AC-3 version number */ + bsi->bsid = mpeg3bits_getbits(audio->astream, 5); + +/* Get the audio service provided by the steram */ + bsi->bsmod = mpeg3bits_getbits(audio->astream, 3); + +/* Get the audio coding mode (ie how many channels)*/ + bsi->acmod = mpeg3bits_getbits(audio->astream, 3); + +/* Predecode the number of full bandwidth channels as we use this + * number a lot */ + bsi->nfchans = mpeg3_ac3_acmodes[bsi->acmod]; + audio->channels = bsi->nfchans; + +/* If it is in use, get the centre channel mix level */ + if((bsi->acmod & 0x1) && (bsi->acmod != 0x1)) + bsi->cmixlev = mpeg3bits_getbits(audio->astream, 2); + +/* If it is in use, get the surround channel mix level */ + if(bsi->acmod & 0x4) + bsi->surmixlev = mpeg3bits_getbits(audio->astream, 2); + +/* Get the dolby surround mode if in 2/0 mode */ + if(bsi->acmod == 0x2) + bsi->dsurmod= mpeg3bits_getbits(audio->astream, 2); + +/* Is the low frequency effects channel on? */ + bsi->lfeon = mpeg3bits_getbits(audio->astream, 1); + +/* Get the dialogue normalization level */ + bsi->dialnorm = mpeg3bits_getbits(audio->astream, 5); + +/* Does compression gain exist? */ + bsi->compre = mpeg3bits_getbits(audio->astream, 1); + if (bsi->compre) + { +/* Get compression gain */ + bsi->compr = mpeg3bits_getbits(audio->astream, 8); + } + +/* Does language code exist? */ + bsi->langcode = mpeg3bits_getbits(audio->astream, 1); + if (bsi->langcode) + { +/* Get langauge code */ + bsi->langcod = mpeg3bits_getbits(audio->astream, 8); + } + +/* Does audio production info exist? */ + bsi->audprodie = mpeg3bits_getbits(audio->astream, 1); + if (bsi->audprodie) + { +/* Get mix level */ + bsi->mixlevel = mpeg3bits_getbits(audio->astream, 5); + +/* Get room type */ + bsi->roomtyp = mpeg3bits_getbits(audio->astream, 2); + } + +/* If we're in dual mono mode then get some extra info */ + if (bsi->acmod == 0) + { +/* Get the dialogue normalization level two */ + bsi->dialnorm2 = mpeg3bits_getbits(audio->astream, 5); + +/* Does compression gain two exist? */ + bsi->compr2e = mpeg3bits_getbits(audio->astream, 1); + if (bsi->compr2e) + { +/* Get compression gain two */ + bsi->compr2 = mpeg3bits_getbits(audio->astream, 8); + } + +/* Does language code two exist? */ + bsi->langcod2e = mpeg3bits_getbits(audio->astream, 1); + if (bsi->langcod2e) + { +/* Get langauge code two */ + bsi->langcod2 = mpeg3bits_getbits(audio->astream, 8); + } + +/* Does audio production info two exist? */ + bsi->audprodi2e = mpeg3bits_getbits(audio->astream, 1); + if (bsi->audprodi2e) + { +/* Get mix level two */ + bsi->mixlevel2 = mpeg3bits_getbits(audio->astream, 5); + +/* Get room type two */ + bsi->roomtyp2 = mpeg3bits_getbits(audio->astream, 2); + } + } + +/* Get the copyright bit */ + bsi->copyrightb = mpeg3bits_getbits(audio->astream, 1); + +/* Get the original bit */ + bsi->origbs = mpeg3bits_getbits(audio->astream, 1); + +/* Does timecode one exist? */ + bsi->timecod1e = mpeg3bits_getbits(audio->astream, 1); + + if(bsi->timecod1e) + bsi->timecod1 = mpeg3bits_getbits(audio->astream, 14); + +/* Does timecode two exist? */ + bsi->timecod2e = mpeg3bits_getbits(audio->astream, 1); + + if(bsi->timecod2e) + bsi->timecod2 = mpeg3bits_getbits(audio->astream, 14); + +/* Does addition info exist? */ + bsi->addbsie = mpeg3bits_getbits(audio->astream, 1); + + if(bsi->addbsie) + { +/* Get how much info is there */ + bsi->addbsil = mpeg3bits_getbits(audio->astream, 6); + +/* Get the additional info */ + for(i = 0; i < (bsi->addbsil + 1); i++) + bsi->addbsi[i] = mpeg3bits_getbits(audio->astream, 8); + } + + if(mpeg3bits_eof(audio->astream)) + { + mpeg3bits_use_demuxer(audio->astream); + return 1; + } +// return mpeg3bits_error(audio->astream); +} + +int mpeg3audio_read_ac3_audblk(mpeg3audio_t *audio) +{ + int i, j; + mpeg3_ac3bsi_t *bsi = &(audio->ac3_bsi); + mpeg3_ac3audblk_t *audblk = &(audio->ac3_audblk); + + for(i = 0; i < bsi->nfchans; i++) + { +/* Is this channel an interleaved 256 + 256 block ? */ + audblk->blksw[i] = mpeg3bits_getbits(audio->astream, 1); + } + + for(i = 0; i < bsi->nfchans; i++) + { +/* Should we dither this channel? */ + audblk->dithflag[i] = mpeg3bits_getbits(audio->astream, 1); + } + +/* Does dynamic range control exist? */ + audblk->dynrnge = mpeg3bits_getbits(audio->astream, 1); + if(audblk->dynrnge) + { +/* Get dynamic range info */ + audblk->dynrng = mpeg3bits_getbits(audio->astream, 8); + } + +/* If we're in dual mono mode then get the second channel DR info */ + if(bsi->acmod == 0) + { +/* Does dynamic range control two exist? */ + audblk->dynrng2e = mpeg3bits_getbits(audio->astream, 1); + if (audblk->dynrng2e) + { +/* Get dynamic range info */ + audblk->dynrng2 = mpeg3bits_getbits(audio->astream, 8); + } + } + +/* Does coupling strategy exist? */ + audblk->cplstre = mpeg3bits_getbits(audio->astream, 1); + if(audblk->cplstre) + { +/* Is coupling turned on? */ + audblk->cplinu = mpeg3bits_getbits(audio->astream, 1); + if(audblk->cplinu) + { + for(i = 0; i < bsi->nfchans; i++) + audblk->chincpl[i] = mpeg3bits_getbits(audio->astream, 1); + + if(bsi->acmod == 0x2) + audblk->phsflginu = mpeg3bits_getbits(audio->astream, 1); + + audblk->cplbegf = mpeg3bits_getbits(audio->astream, 4); + audblk->cplendf = mpeg3bits_getbits(audio->astream, 4); + audblk->ncplsubnd = (audblk->cplendf + 2) - audblk->cplbegf + 1; + +/* Calculate the start and end bins of the coupling channel */ + audblk->cplstrtmant = (audblk->cplbegf * 12) + 37 ; + audblk->cplendmant = ((audblk->cplendf + 3) * 12) + 37; + +/* The number of combined subbands is ncplsubnd minus each combined band */ + audblk->ncplbnd = audblk->ncplsubnd; + + for(i = 1; i < audblk->ncplsubnd; i++) + { + audblk->cplbndstrc[i] = mpeg3bits_getbits(audio->astream, 1); + audblk->ncplbnd -= audblk->cplbndstrc[i]; + } + } + } + + if(audblk->cplinu) + { +/* Loop through all the channels and get their coupling co-ords */ + for(i = 0; i < bsi->nfchans; i++) + { + if(!audblk->chincpl[i]) + continue; + +/* Is there new coupling co-ordinate info? */ + audblk->cplcoe[i] = mpeg3bits_getbits(audio->astream, 1); + + if(audblk->cplcoe[i]) + { + audblk->mstrcplco[i] = mpeg3bits_getbits(audio->astream, 2); + for(j = 0; j < audblk->ncplbnd; j++) + { + audblk->cplcoexp[i][j] = mpeg3bits_getbits(audio->astream, 4); + audblk->cplcomant[i][j] = mpeg3bits_getbits(audio->astream, 4); + } + } + } + +/* If we're in dual mono mode, there's going to be some phase info */ + if((bsi->acmod == 0x2) && audblk->phsflginu && + (audblk->cplcoe[0] || audblk->cplcoe[1])) + { + for(j = 0; j < audblk->ncplbnd; j++) + { + audblk->phsflg[j] = mpeg3bits_getbits(audio->astream, 1); + } + } + } + +/* If we're in dual mono mode, there may be a rematrix strategy */ + if(bsi->acmod == 0x2) + { + audblk->rematstr = mpeg3bits_getbits(audio->astream, 1); + if(audblk->rematstr) + { + if (audblk->cplinu == 0) + { + for(i = 0; i < 4; i++) + audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1); + } + if((audblk->cplbegf > 2) && audblk->cplinu) + { + for(i = 0; i < 4; i++) + audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1); + } + if((audblk->cplbegf <= 2) && audblk->cplinu) + { + for(i = 0; i < 3; i++) + audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1); + } + if((audblk->cplbegf == 0) && audblk->cplinu) + for(i = 0; i < 2; i++) + audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1); + + } + } + + if (audblk->cplinu) + { +/* Get the coupling channel exponent strategy */ + audblk->cplexpstr = mpeg3bits_getbits(audio->astream, 2); + + if(audblk->cplexpstr == 0) + audblk->ncplgrps = 0; + else + audblk->ncplgrps = (audblk->cplendmant - audblk->cplstrtmant) / + (3 << (audblk->cplexpstr - 1)); + + } + + for(i = 0; i < bsi->nfchans; i++) + { + audblk->chexpstr[i] = mpeg3bits_getbits(audio->astream, 2); + } + +/* Get the exponent strategy for lfe channel */ + if(bsi->lfeon) + audblk->lfeexpstr = mpeg3bits_getbits(audio->astream, 1); + +/* Determine the bandwidths of all the fbw channels */ + for(i = 0; i < bsi->nfchans; i++) + { + unsigned short grp_size; + + if(audblk->chexpstr[i] != MPEG3_EXP_REUSE) + { + if (audblk->cplinu && audblk->chincpl[i]) + { + audblk->endmant[i] = audblk->cplstrtmant; + } + else + { + audblk->chbwcod[i] = mpeg3bits_getbits(audio->astream, 6); + audblk->endmant[i] = ((audblk->chbwcod[i] + 12) * 3) + 37; + } + +/* Calculate the number of exponent groups to fetch */ + grp_size = 3 * (1 << (audblk->chexpstr[i] - 1)); + audblk->nchgrps[i] = (audblk->endmant[i] - 1 + (grp_size - 3)) / grp_size; + } + } + +/* Get the coupling exponents if they exist */ + if(audblk->cplinu && (audblk->cplexpstr != MPEG3_EXP_REUSE)) + { + audblk->cplabsexp = mpeg3bits_getbits(audio->astream, 4); + for(i = 0; i< audblk->ncplgrps; i++) + audblk->cplexps[i] = mpeg3bits_getbits(audio->astream, 7); + } + +/* Get the fwb channel exponents */ + for(i = 0; i < bsi->nfchans; i++) + { + if(audblk->chexpstr[i] != MPEG3_EXP_REUSE) + { + audblk->exps[i][0] = mpeg3bits_getbits(audio->astream, 4); + for(j = 1; j <= audblk->nchgrps[i]; j++) + audblk->exps[i][j] = mpeg3bits_getbits(audio->astream, 7); + audblk->gainrng[i] = mpeg3bits_getbits(audio->astream, 2); + } + } + +/* Get the lfe channel exponents */ + if(bsi->lfeon && (audblk->lfeexpstr != MPEG3_EXP_REUSE)) + { + audblk->lfeexps[0] = mpeg3bits_getbits(audio->astream, 4); + audblk->lfeexps[1] = mpeg3bits_getbits(audio->astream, 7); + audblk->lfeexps[2] = mpeg3bits_getbits(audio->astream, 7); + } + +/* Get the parametric bit allocation parameters */ + audblk->baie = mpeg3bits_getbits(audio->astream, 1); + + if(audblk->baie) + { + audblk->sdcycod = mpeg3bits_getbits(audio->astream, 2); + audblk->fdcycod = mpeg3bits_getbits(audio->astream, 2); + audblk->sgaincod = mpeg3bits_getbits(audio->astream, 2); + audblk->dbpbcod = mpeg3bits_getbits(audio->astream, 2); + audblk->floorcod = mpeg3bits_getbits(audio->astream, 3); + } + + +/* Get the SNR off set info if it exists */ + audblk->snroffste = mpeg3bits_getbits(audio->astream, 1); + + if(audblk->snroffste) + { + audblk->csnroffst = mpeg3bits_getbits(audio->astream, 6); + + if(audblk->cplinu) + { + audblk->cplfsnroffst = mpeg3bits_getbits(audio->astream, 4); + audblk->cplfgaincod = mpeg3bits_getbits(audio->astream, 3); + } + + for(i = 0; i < bsi->nfchans; i++) + { + audblk->fsnroffst[i] = mpeg3bits_getbits(audio->astream, 4); + audblk->fgaincod[i] = mpeg3bits_getbits(audio->astream, 3); + } + if(bsi->lfeon) + { + + audblk->lfefsnroffst = mpeg3bits_getbits(audio->astream, 4); + audblk->lfefgaincod = mpeg3bits_getbits(audio->astream, 3); + } + } + +/* Get coupling leakage info if it exists */ + if(audblk->cplinu) + { + audblk->cplleake = mpeg3bits_getbits(audio->astream, 1); + + if(audblk->cplleake) + { + audblk->cplfleak = mpeg3bits_getbits(audio->astream, 3); + audblk->cplsleak = mpeg3bits_getbits(audio->astream, 3); + } + } + +/* Get the delta bit alloaction info */ + audblk->deltbaie = mpeg3bits_getbits(audio->astream, 1); + + if(audblk->deltbaie) + { + if(audblk->cplinu) + audblk->cpldeltbae = mpeg3bits_getbits(audio->astream, 2); + + for(i = 0; i < bsi->nfchans; i++) + audblk->deltbae[i] = mpeg3bits_getbits(audio->astream, 2); + + if (audblk->cplinu && (audblk->cpldeltbae == DELTA_BIT_NEW)) + { + audblk->cpldeltnseg = mpeg3bits_getbits(audio->astream, 3); + for(i = 0; i < audblk->cpldeltnseg + 1; i++) + { + audblk->cpldeltoffst[i] = mpeg3bits_getbits(audio->astream, 5); + audblk->cpldeltlen[i] = mpeg3bits_getbits(audio->astream, 4); + audblk->cpldeltba[i] = mpeg3bits_getbits(audio->astream, 3); + } + } + + for(i = 0; i < bsi->nfchans; i++) + { + if (audblk->deltbae[i] == DELTA_BIT_NEW) + { + audblk->deltnseg[i] = mpeg3bits_getbits(audio->astream, 3); + for(j = 0; j < audblk->deltnseg[i] + 1; j++) + { + audblk->deltoffst[i][j] = mpeg3bits_getbits(audio->astream, 5); + audblk->deltlen[i][j] = mpeg3bits_getbits(audio->astream, 4); + audblk->deltba[i][j] = mpeg3bits_getbits(audio->astream, 3); + } + } + } + } + +/* Check to see if there's any dummy info to get */ + if((audblk->skiple = mpeg3bits_getbits(audio->astream, 1))) + { + unsigned int skip_data; + audblk->skipl = mpeg3bits_getbits(audio->astream, 9); + for(i = 0; i < audblk->skipl ; i++) + { + skip_data = mpeg3bits_getbits(audio->astream, 8); + } + } + + return mpeg3bits_error(audio->astream); +} + + +/* This routine simply does stereo rematrixing for the 2 channel + * stereo mode */ +int mpeg3audio_ac3_rematrix(mpeg3_ac3audblk_t *audblk, + mpeg3ac3_stream_samples_t samples) +{ + int num_bands; + int start; + int end; + int i, j; + mpeg3_real_t left, right; + + if(audblk->cplinu || audblk->cplbegf > 2) + num_bands = 4; + else if (audblk->cplbegf > 0) + num_bands = 3; + else + num_bands = 2; + + for(i = 0; i < num_bands; i++) + { + if(!audblk->rematflg[i]) + continue; + + start = mpeg3_rematrix_band[i].start; + end = mpeg3_min(mpeg3_rematrix_band[i].end, 12 * audblk->cplbegf + 36); + + for(j = start; j < end; j++) + { + left = samples[0][j] + samples[1][j]; + right = samples[0][j] - samples[1][j]; + samples[0][j] = left; + samples[1][j] = right; + } + } + return 0; +} + + +int mpeg3audio_ac3_reset_frame(mpeg3audio_t *audio) +{ + memset(&audio->ac3_bit_allocation, 0, sizeof(mpeg3_ac3_bitallocation_t)); + memset(&audio->ac3_mantissa, 0, sizeof(mpeg3_ac3_mantissa_t)); + memset(&audio->ac3_audblk, 0, sizeof(mpeg3_ac3audblk_t)); + + return 0; +} + +int mpeg3audio_do_ac3(mpeg3audio_t *audio) +{ + int result = 0, i; + +/* Reset the coefficients and exponents */ + mpeg3audio_ac3_reset_frame(audio); + + for(i = 0; i < 6 && !result; i++) + { + memset(audio->ac3_samples, 0, sizeof(mpeg3_real_t) * 256 * (audio->ac3_bsi.nfchans + audio->ac3_bsi.lfeon)); +/* Extract most of the audblk info from the bitstream + * (minus the mantissas */ + result |= mpeg3audio_read_ac3_audblk(audio); + +/* Take the differential exponent data and turn it into + * absolute exponents */ + if(!result) result |= mpeg3audio_ac3_exponent_unpack(audio, + &(audio->ac3_bsi), + &(audio->ac3_audblk)); + +/* Figure out how many bits per mantissa */ + if(!result) result |= mpeg3audio_ac3_bit_allocate(audio, + audio->sampling_frequency_code, + &(audio->ac3_bsi), + &(audio->ac3_audblk)); + +/* Extract the mantissas from the data stream */ + if(!result) result |= mpeg3audio_ac3_coeff_unpack(audio, + &(audio->ac3_bsi), + &(audio->ac3_audblk), + audio->ac3_samples); + + if(audio->ac3_bsi.acmod == 0x2) + if(!result) result |= mpeg3audio_ac3_rematrix(&(audio->ac3_audblk), + audio->ac3_samples); + +/* Convert the frequency data into time samples */ + if(!result) result |= mpeg3audio_ac3_imdct(audio, + &(audio->ac3_bsi), + &(audio->ac3_audblk), + audio->ac3_samples); + + if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels) + { +/* Need more room */ + mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels); + } + } + + mpeg3bits_use_demuxer(audio->astream); + + return result; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/ac3.h b/core/multimedia/opieplayer/libmpeg3/audio/ac3.h new file mode 100644 index 0000000..9161c36 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/ac3.h @@ -0,0 +1,308 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef AC3_H +#define AC3_H + +#include "mpeg3real.h" + +#define MAX_AC3_FRAMESIZE 1920 * 2 + 512 + +extern int mpeg3_ac3_samplerates[3]; + +/* Exponent strategy constants */ +#define MPEG3_EXP_REUSE (0) +#define MPEG3_EXP_D15 (1) +#define MPEG3_EXP_D25 (2) +#define MPEG3_EXP_D45 (3) + +/* Delta bit allocation constants */ +#define DELTA_BIT_REUSE (0) +#define DELTA_BIT_NEW (1) +#define DELTA_BIT_NONE (2) +#define DELTA_BIT_RESERVED (3) + + +typedef mpeg3_real_t mpeg3ac3_stream_samples_t[6][256]; + +typedef struct +{ +/* Bit stream identification == 0x8 */ + int bsid; +/* Bit stream mode */ + int bsmod; +/* Audio coding mode */ + int acmod; +/* If we're using the centre channel then */ +/* centre mix level */ + int cmixlev; +/* If we're using the surround channel then */ +/* surround mix level */ + int surmixlev; +/* If we're in 2/0 mode then */ +/* Dolby surround mix level - NOT USED - */ + int dsurmod; +/* Low frequency effects on */ + int lfeon; +/* Dialogue Normalization level */ + int dialnorm; +/* Compression exists */ + int compre; +/* Compression level */ + int compr; +/* Language code exists */ + int langcode; +/* Language code */ + int langcod; +/* Audio production info exists*/ + unsigned int audprodie; + int mixlevel; + int roomtyp; +/* If we're in dual mono mode (acmod == 0) then extra stuff */ + int dialnorm2; + int compr2e; + int compr2; + int langcod2e; + int langcod2; + int audprodi2e; + int mixlevel2; + int roomtyp2; +/* Copyright bit */ + int copyrightb; +/* Original bit */ + int origbs; +/* Timecode 1 exists */ + int timecod1e; +/* Timecode 1 */ + unsigned int timecod1; +/* Timecode 2 exists */ + int timecod2e; +/* Timecode 2 */ + unsigned int timecod2; +/* Additional bit stream info exists */ + int addbsie; +/* Additional bit stream length - 1 (in bytes) */ + int addbsil; +/* Additional bit stream information (max 64 bytes) */ + unsigned char addbsi[64]; + +/* Information not in the AC-3 bitstream, but derived */ +/* Number of channels (excluding LFE) + * Derived from acmod */ + int nfchans; +} mpeg3_ac3bsi_t; + +typedef struct +{ +/* block switch bit indexed by channel num */ + unsigned short blksw[5]; +/* dither enable bit indexed by channel num */ + unsigned short dithflag[5]; +/* dynamic range gain exists */ + int dynrnge; +/* dynamic range gain */ + int dynrng; +/* if acmod==0 then */ +/* dynamic range 2 gain exists */ + int dynrng2e; +/* dynamic range 2 gain */ + int dynrng2; +/* coupling strategy exists */ + int cplstre; +/* coupling in use */ + int cplinu; +/* channel coupled */ + unsigned short chincpl[5]; +/* if acmod==2 then */ +/* Phase flags in use */ + int phsflginu; +/* coupling begin frequency code */ + int cplbegf; +/* coupling end frequency code */ + int cplendf; +/* coupling band structure bits */ + unsigned short cplbndstrc[18]; +/* Do coupling co-ords exist for this channel? */ + unsigned short cplcoe[5]; +/* Master coupling co-ordinate */ + unsigned short mstrcplco[5]; +/* Per coupling band coupling co-ordinates */ + unsigned short cplcoexp[5][18]; + unsigned short cplcomant[5][18]; +/* Phase flags for dual mono */ + unsigned short phsflg[18]; +/* Is there a rematrixing strategy */ + unsigned int rematstr; +/* Rematrixing bits */ + unsigned short rematflg[4]; +/* Coupling exponent strategy */ + int cplexpstr; +/* Exponent strategy for full bandwidth channels */ + unsigned short chexpstr[5]; +/* Exponent strategy for lfe channel */ + int lfeexpstr; +/* Channel bandwidth for independent channels */ + unsigned short chbwcod[5]; +/* The absolute coupling exponent */ + int cplabsexp; +/* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */ + unsigned short cplexps[18 * 12 / 3]; +/* fbw channel exponents */ + unsigned short exps[5][252 / 3]; +/* channel gain range */ + unsigned short gainrng[5]; +/* low frequency exponents */ + unsigned short lfeexps[3]; + +/* Bit allocation info */ + int baie; +/* Slow decay code */ + int sdcycod; +/* Fast decay code */ + int fdcycod; +/* Slow gain code */ + int sgaincod; +/* dB per bit code */ + int dbpbcod; +/* masking floor code */ + int floorcod; + +/* SNR offset info */ + int snroffste; +/* coarse SNR offset */ + int csnroffst; +/* coupling fine SNR offset */ + int cplfsnroffst; +/* coupling fast gain code */ + int cplfgaincod; +/* fbw fine SNR offset */ + unsigned short fsnroffst[5]; +/* fbw fast gain code */ + unsigned short fgaincod[5]; +/* lfe fine SNR offset */ + int lfefsnroffst; +/* lfe fast gain code */ + int lfefgaincod; + +/* Coupling leak info */ + int cplleake; +/* coupling fast leak initialization */ + int cplfleak; +/* coupling slow leak initialization */ + int cplsleak; + +/* delta bit allocation info */ + int deltbaie; +/* coupling delta bit allocation exists */ + int cpldeltbae; +/* fbw delta bit allocation exists */ + unsigned short deltbae[5]; +/* number of cpl delta bit segments */ + int cpldeltnseg; +/* coupling delta bit allocation offset */ + short cpldeltoffst[8]; +/* coupling delta bit allocation length */ + short cpldeltlen[8]; +/* coupling delta bit allocation length */ + short cpldeltba[8]; +/* number of delta bit segments */ + unsigned short deltnseg[5]; +/* fbw delta bit allocation offset */ + short deltoffst[5][8]; +/* fbw delta bit allocation length */ + short deltlen[5][8]; +/* fbw delta bit allocation length */ + short deltba[5][8]; + +/* skip length exists */ + int skiple; +/* skip length */ + int skipl; + +/* channel mantissas */ + short chmant[5][256]; + +/* coupling mantissas */ + unsigned short cplmant[256]; + +/* coupling mantissas */ + unsigned short lfemant[7]; + +/* -- Information not in the bitstream, but derived thereof -- */ + +/* Number of coupling sub-bands */ + int ncplsubnd; + +/* Number of combined coupling sub-bands + * Derived from ncplsubnd and cplbndstrc */ + int ncplbnd; + +/* Number of exponent groups by channel + * Derived from strmant, endmant */ + int nchgrps[5]; + +/* Number of coupling exponent groups + * Derived from cplbegf, cplendf, cplexpstr */ + int ncplgrps; + +/* End mantissa numbers of fbw channels */ + unsigned short endmant[5]; + +/* Start and end mantissa numbers for the coupling channel */ + int cplstrtmant; + int cplendmant; + +/* Decoded exponent info */ + unsigned short fbw_exp[5][256]; + unsigned short cpl_exp[256]; + unsigned short lfe_exp[7]; + +/* Bit allocation pointer results */ + short fbw_bap[5][256]; +/*FIXME figure out exactly how many entries there should be (253-37?) */ + short cpl_bap[256]; + short lfe_bap[7]; +} mpeg3_ac3audblk_t; + +/* Bit allocation data */ +typedef struct +{ + int sdecay; + int fdecay; + int sgain; + int dbknee; + int floor; + short psd[256]; + short bndpsd[256]; + short excite[256]; + short mask[256]; +} mpeg3_ac3_bitallocation_t; + +/* Mantissa data */ +typedef struct +{ + unsigned short m_1[3]; + unsigned short m_2[3]; + unsigned short m_4[2]; + unsigned short m_1_pointer; + unsigned short m_2_pointer; + unsigned short m_4_pointer; +} mpeg3_ac3_mantissa_t; + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/audio/bit_allocation.c b/core/multimedia/opieplayer/libmpeg3/audio/bit_allocation.c new file mode 100644 index 0000000..29df7d7 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/bit_allocation.c @@ -0,0 +1,586 @@ +/* + * + * Copyright (C) Aaron Holtzman - May 1999 + * + * + * This file is part of libmpeg3 + * + * libmpeg3 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * libmpeg3 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include +#include + +/* Bit allocation tables */ + +static short mpeg3_slowdec[] = { 0x0f, 0x11, 0x13, 0x15 }; +static short mpeg3_fastdec[] = { 0x3f, 0x53, 0x67, 0x7b }; +static short mpeg3_slowgain[] = { 0x540, 0x4d8, 0x478, 0x410 }; +static short mpeg3_dbpbtab[] = { 0x000, 0x700, 0x900, 0xb00 }; + +static unsigned short mpeg3_floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 }; +static short mpeg3_fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 }; + + +static short mpeg3_bndtab[] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, + 34, 37, 40, 43, 46, 49, 55, 61, 67, 73, + 79, 85, 97, 109, 121, 133, 157, 181, 205, 229 +}; + +static short mpeg3_bndsz[] = +{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, + 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, + 6, 12, 12, 12, 12, 24, 24, 24, 24, 24 +}; + +static short mpeg3_masktab[] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29, + 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, + 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, + 37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40, + 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0 +}; + + +static short mpeg3_latab[] = +{ + 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039, + 0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032, + 0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c, + 0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026, + 0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021, + 0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c, + 0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018, + 0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015, + 0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012, + 0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f, + 0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d, + 0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static short mpeg3_hth[][50] = +{ + { + 0x04d0, 0x04d0, 0x0440, 0x0400, 0x03e0, 0x03c0, 0x03b0, 0x03b0, + 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, + 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350, + 0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, + 0x02f0, 0x02f0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03e0, 0x0420, + 0x0460, 0x0490, 0x04a0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800, + 0x0840, 0x0840 + }, + + { + 0x04f0, 0x04f0, 0x0460, 0x0410, 0x03e0, 0x03d0, 0x03c0, 0x03b0, + 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, + 0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, + 0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310, 0x0300, 0x02f0, + 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03e0, + 0x0420, 0x0450, 0x04a0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630, + 0x0840, 0x0840 + }, + + { + 0x0580, 0x0580, 0x04b0, 0x0450, 0x0420, 0x03f0, 0x03e0, 0x03d0, + 0x03c0, 0x03b0, 0x03b0, 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, + 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, 0x0390, + 0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350, 0x0340, 0x0330, + 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0310, + 0x0330, 0x0350, 0x03c0, 0x0410, 0x0470, 0x04a0, 0x0460, 0x0440, + 0x0450, 0x04e0 + } +}; + + +static short mpeg3_baptab[] = +{ + 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15 +}; + + +inline int logadd(int a, int b) +{ + int c; + int address; + + c = a - b; + address = mpeg3_min((abs(c) >> 1), 255); + + if(c >= 0) + return(a + mpeg3_latab[address]); + else + return(b + mpeg3_latab[address]); +} + + +int mpeg3audio_ac3_calc_lowcomp(int a, int b0, int b1, int bin) +{ + if(bin < 7) + { + if((b0 + 256) == b1) + a = 384; + else + if(b0 > b1) + a = mpeg3_max(0, a - 64); + } + else if(bin < 20) + { + if((b0 + 256) == b1) + a = 320; + else if(b0 > b1) + a = mpeg3_max(0, a - 64) ; + } + else + a = mpeg3_max(0, a - 128); + + return(a); +} + +void mpeg3audio_ac3_ba_compute_psd(int start, + int end, + unsigned short exps[], + short psd[], + short bndpsd[]) +{ + int bin,i,j,k; + int lastbin = 0; + +/* Map the exponents into dBs */ + for (bin = start; bin < end; bin++) + { + psd[bin] = (3072 - (exps[bin] << 7)); + } + +/* Integrate the psd function over each bit allocation band */ + j = start; + k = mpeg3_masktab[start]; + + do + { + lastbin = mpeg3_min(mpeg3_bndtab[k] + mpeg3_bndsz[k], end); + bndpsd[k] = psd[j]; + j++; + + for(i = j; i < lastbin; i++) + { + bndpsd[k] = logadd(bndpsd[k], psd[j]); + j++; + } + + k++; + }while(end > lastbin); +} + +void mpeg3audio_ac3_ba_compute_excitation(mpeg3audio_t *audio, + int start, + int end, + int fgain, + int fastleak, + int slowleak, + int is_lfe, + short bndpsd[], + short excite[]) +{ + int bin; + int bndstrt; + int bndend; + int lowcomp = 0; + int begin = 0; + +/* Compute excitation function */ + bndstrt = mpeg3_masktab[start]; + bndend = mpeg3_masktab[end - 1] + 1; + + if(bndstrt == 0) /* For fbw and lfe channels */ + { + lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0); + excite[0] = bndpsd[0] - fgain - lowcomp; + lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1); + excite[1] = bndpsd[1] - fgain - lowcomp; + begin = 7 ; + +/* Note: Do not call mpeg3audio_ac3_calc_lowcomp() for the last band of the lfe channel, (bin = 6) */ + for (bin = 2; bin < 7; bin++) + { + if(!(is_lfe && (bin == 6))) + lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); + fastleak = bndpsd[bin] - fgain; + slowleak = bndpsd[bin] - audio->ac3_bit_allocation.sgain; + excite[bin] = fastleak - lowcomp; + + if(!(is_lfe && (bin == 6))) + { + if(bndpsd[bin] <= bndpsd[bin+1]) + { + begin = bin + 1 ; + break; + } + } + } + + for (bin = begin; bin < mpeg3_min(bndend, 22); bin++) + { + if (!(is_lfe && (bin == 6))) + lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); + fastleak -= audio->ac3_bit_allocation.fdecay; + fastleak = mpeg3_max(fastleak, bndpsd[bin] - fgain); + slowleak -= audio->ac3_bit_allocation.sdecay; + slowleak = mpeg3_max(slowleak, bndpsd[bin] - audio->ac3_bit_allocation.sgain); + excite[bin] = mpeg3_max(fastleak - lowcomp, slowleak); + } + begin = 22; + } + else /* For coupling channel */ + { + begin = bndstrt; + } + + for (bin = begin; bin < bndend; bin++) + { + fastleak -= audio->ac3_bit_allocation.fdecay; + fastleak = mpeg3_max(fastleak, bndpsd[bin] - fgain); + slowleak -= audio->ac3_bit_allocation.sdecay; + slowleak = mpeg3_max(slowleak, bndpsd[bin] - audio->ac3_bit_allocation.sgain); + excite[bin] = mpeg3_max(fastleak, slowleak) ; + } +} + +void mpeg3audio_ac3_ba_compute_mask(mpeg3audio_t *audio, + int start, + int end, + int fscod, + int deltbae, + int deltnseg, + short deltoffst[], + short deltba[], + short deltlen[], + short excite[], + short mask[]) +{ + int bin, k; + int bndstrt; + int bndend; + int delta; + + bndstrt = mpeg3_masktab[start]; + bndend = mpeg3_masktab[end - 1] + 1; + +/* Compute the masking curve */ + + for (bin = bndstrt; bin < bndend; bin++) + { + if (audio->ac3_bit_allocation.bndpsd[bin] < audio->ac3_bit_allocation.dbknee) + { + excite[bin] += ((audio->ac3_bit_allocation.dbknee - audio->ac3_bit_allocation.bndpsd[bin]) >> 2); + } + mask[bin] = mpeg3_max(excite[bin], mpeg3_hth[fscod][bin]); + } + +/* Perform delta bit modulation if necessary */ + if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW)) + { + int band = 0; + int seg = 0; + + for (seg = 0; seg < deltnseg + 1; seg++) + { + band += deltoffst[seg]; + if (deltba[seg] >= 4) + { + delta = (deltba[seg] - 3) << 7; + } + else + { + delta = (deltba[seg] - 4) << 7; + } + + for (k = 0; k < deltlen[seg]; k++) + { + mask[band] += delta; + band++; + } + } + } +} + +void mpeg3audio_ac3_ba_compute_bap(mpeg3audio_t *audio, + int start, + int end, + int snroffset, + short psd[], + short mask[], + short bap[]) +{ + int i, j, k; + short lastbin = 0; + short address = 0; + +/* Compute the bit allocation pointer for each bin */ + i = start; + j = mpeg3_masktab[start]; + + do + { + lastbin = mpeg3_min(mpeg3_bndtab[j] + mpeg3_bndsz[j], end); + mask[j] -= snroffset; + mask[j] -= audio->ac3_bit_allocation.floor; + + if(mask[j] < 0) + mask[j] = 0; + + mask[j] &= 0x1fe0; + mask[j] += audio->ac3_bit_allocation.floor; + for(k = i; k < lastbin; k++) + { + address = (psd[i] - mask[j]) >> 5; + address = mpeg3_min(63, mpeg3_max(0, address)); + bap[i] = mpeg3_baptab[address]; + i++; + } + j++; + }while (end > lastbin); +} + +int mpeg3audio_ac3_bit_allocate(mpeg3audio_t *audio, + unsigned int fscod, + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk) +{ + int result = 0; + int i; + int fgain; + int snroffset; + int start; + int end; + int fastleak; + int slowleak; + +/*printf("mpeg3audio_ac3_bit_allocate %d %d %d %d %d\n", audblk->sdcycod, audblk->fdcycod, audblk->sgaincod, audblk->dbpbcod, audblk->floorcod); */ +/* Only perform bit_allocation if the exponents have changed or we + * have new sideband information */ + if(audblk->chexpstr[0] == 0 && audblk->chexpstr[1] == 0 && + audblk->chexpstr[2] == 0 && audblk->chexpstr[3] == 0 && + audblk->chexpstr[4] == 0 && audblk->cplexpstr == 0 && + audblk->lfeexpstr == 0 && audblk->baie == 0 && + audblk->snroffste == 0 && audblk->deltbaie == 0) + return 0; + +/* Do some setup before we do the bit alloc */ + audio->ac3_bit_allocation.sdecay = mpeg3_slowdec[audblk->sdcycod]; + audio->ac3_bit_allocation.fdecay = mpeg3_fastdec[audblk->fdcycod]; + audio->ac3_bit_allocation.sgain = mpeg3_slowgain[audblk->sgaincod]; + audio->ac3_bit_allocation.dbknee = mpeg3_dbpbtab[audblk->dbpbcod]; + audio->ac3_bit_allocation.floor = mpeg3_floortab[audblk->floorcod]; + +/* if all the SNR offset constants are zero then the whole block is zero */ + if(!audblk->csnroffst && !audblk->fsnroffst[0] && + !audblk->fsnroffst[1] && !audblk->fsnroffst[2] && + !audblk->fsnroffst[3] && !audblk->fsnroffst[4] && + !audblk->cplfsnroffst && !audblk->lfefsnroffst) + { + memset(audblk->fbw_bap, 0, sizeof(short) * 256 * 5); + memset(audblk->cpl_bap, 0, sizeof(short) * 256); + memset(audblk->lfe_bap, 0, sizeof(short) * 7); + return 0; + } + + for(i = 0; i < bsi->nfchans; i++) + { + start = 0; + end = audblk->endmant[i]; + fgain = mpeg3_fastgain[audblk->fgaincod[i]]; + snroffset = (((audblk->csnroffst - 15) << 4) + audblk->fsnroffst[i]) << 2 ; + fastleak = 0; + slowleak = 0; + + mpeg3audio_ac3_ba_compute_psd(start, + end, + audblk->fbw_exp[i], + audio->ac3_bit_allocation.psd, + audio->ac3_bit_allocation.bndpsd); + + mpeg3audio_ac3_ba_compute_excitation(audio, + start, + end , + fgain, + fastleak, + slowleak, + 0, + audio->ac3_bit_allocation.bndpsd, + audio->ac3_bit_allocation.excite); + + mpeg3audio_ac3_ba_compute_mask(audio, + start, + end, + fscod, + audblk->deltbae[i], + audblk->deltnseg[i], + audblk->deltoffst[i], + audblk->deltba[i], + audblk->deltlen[i], + audio->ac3_bit_allocation.excite, + audio->ac3_bit_allocation.mask); + + mpeg3audio_ac3_ba_compute_bap(audio, + start, + end, + snroffset, + audio->ac3_bit_allocation.psd, + audio->ac3_bit_allocation.mask, + audblk->fbw_bap[i]); + } + + if(audblk->cplinu) + { + start = audblk->cplstrtmant; + end = audblk->cplendmant; + fgain = mpeg3_fastgain[audblk->cplfgaincod]; + snroffset = (((audblk->csnroffst - 15) << 4) + audblk->cplfsnroffst) << 2 ; + fastleak = (audblk->cplfleak << 8) + 768; + slowleak = (audblk->cplsleak << 8) + 768; + + mpeg3audio_ac3_ba_compute_psd(start, + end, + audblk->cpl_exp, + audio->ac3_bit_allocation.psd, + audio->ac3_bit_allocation.bndpsd); + + mpeg3audio_ac3_ba_compute_excitation(audio, + start, + end , + fgain, + fastleak, + slowleak, + 0, + audio->ac3_bit_allocation.bndpsd, + audio->ac3_bit_allocation.excite); + + mpeg3audio_ac3_ba_compute_mask(audio, + start, + end, + fscod, + audblk->cpldeltbae, + audblk->cpldeltnseg, + audblk->cpldeltoffst, + audblk->cpldeltba, + audblk->cpldeltlen, + audio->ac3_bit_allocation.excite, + audio->ac3_bit_allocation.mask); + + mpeg3audio_ac3_ba_compute_bap(audio, + start, + end, + snroffset, + audio->ac3_bit_allocation.psd, + audio->ac3_bit_allocation.mask, + audblk->cpl_bap); + } + + if(bsi->lfeon) + { + start = 0; + end = 7; + fgain = mpeg3_fastgain[audblk->lfefgaincod]; + snroffset = (((audblk->csnroffst - 15) << 4) + audblk->lfefsnroffst) << 2 ; + fastleak = 0; + slowleak = 0; + + mpeg3audio_ac3_ba_compute_psd(start, + end, + audblk->lfe_exp, + audio->ac3_bit_allocation.psd, + audio->ac3_bit_allocation.bndpsd); + + mpeg3audio_ac3_ba_compute_excitation(audio, + start, + end , + fgain, + fastleak, + slowleak, + 1, + audio->ac3_bit_allocation.bndpsd, + audio->ac3_bit_allocation.excite); + +/* Perform no delta bit allocation for lfe */ + mpeg3audio_ac3_ba_compute_mask(audio, + start, + end, + fscod, + 2, + 0, + 0, + 0, + 0, + audio->ac3_bit_allocation.excite, + audio->ac3_bit_allocation.mask); + + mpeg3audio_ac3_ba_compute_bap(audio, + start, + end, + snroffset, + audio->ac3_bit_allocation.psd, + audio->ac3_bit_allocation.mask, + audblk->lfe_bap); + } + + return result; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/c_flags b/core/multimedia/opieplayer/libmpeg3/audio/c_flags new file mode 100755 index 0000000..d7943d0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/c_flags @@ -0,0 +1 @@ +echo $CFLAGS diff --git a/core/multimedia/opieplayer/libmpeg3/audio/dct.c b/core/multimedia/opieplayer/libmpeg3/audio/dct.c new file mode 100644 index 0000000..1fd52ce --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/dct.c @@ -0,0 +1,1135 @@ +/* + * + * This file is part of libmpeg3 + * + * libmpeg3 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * libmpeg3 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * Discrete Cosine Tansform (DCT) for subband synthesis + * optimized for machines with no auto-increment. + * The performance is highly compiler dependend. Maybe + * the dct64.c version for 'normal' processor may be faster + * even for Intel processors. + */ + +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "tables.h" + +#include + +int mpeg3audio_dct64_1(mpeg3_real_t *out0, mpeg3_real_t *out1, mpeg3_real_t *b1, mpeg3_real_t *b2, mpeg3_real_t *samples) +{ + register mpeg3_real_t *costab = mpeg3_pnts[0]; + + b1[0x00] = samples[0x00] + samples[0x1F]; + b1[0x01] = samples[0x01] + samples[0x1E]; + b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0]; + b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1]; + + b1[0x02] = samples[0x02] + samples[0x1D]; + b1[0x03] = samples[0x03] + samples[0x1C]; + b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2]; + b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3]; + + b1[0x04] = samples[0x04] + samples[0x1B]; + b1[0x05] = samples[0x05] + samples[0x1A]; + b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4]; + b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5]; + + b1[0x06] = samples[0x06] + samples[0x19]; + b1[0x07] = samples[0x07] + samples[0x18]; + b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6]; + b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7]; + + b1[0x08] = samples[0x08] + samples[0x17]; + b1[0x09] = samples[0x09] + samples[0x16]; + b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8]; + b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9]; + + b1[0x0A] = samples[0x0A] + samples[0x15]; + b1[0x0B] = samples[0x0B] + samples[0x14]; + b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA]; + b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB]; + + b1[0x0C] = samples[0x0C] + samples[0x13]; + b1[0x0D] = samples[0x0D] + samples[0x12]; + b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC]; + b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD]; + + b1[0x0E] = samples[0x0E] + samples[0x11]; + b1[0x0F] = samples[0x0F] + samples[0x10]; + b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE]; + b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF]; + + costab = mpeg3_pnts[1]; + + b2[0x00] = b1[0x00] + b1[0x0F]; + b2[0x01] = b1[0x01] + b1[0x0E]; + b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0]; + b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1]; + + b2[0x02] = b1[0x02] + b1[0x0D]; + b2[0x03] = b1[0x03] + b1[0x0C]; + b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2]; + b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3]; + + b2[0x04] = b1[0x04] + b1[0x0B]; + b2[0x05] = b1[0x05] + b1[0x0A]; + b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4]; + b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5]; + + b2[0x06] = b1[0x06] + b1[0x09]; + b2[0x07] = b1[0x07] + b1[0x08]; + b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6]; + b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7]; + + /* */ + + b2[0x10] = b1[0x10] + b1[0x1F]; + b2[0x11] = b1[0x11] + b1[0x1E]; + b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0]; + b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1]; + + b2[0x12] = b1[0x12] + b1[0x1D]; + b2[0x13] = b1[0x13] + b1[0x1C]; + b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2]; + b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3]; + + b2[0x14] = b1[0x14] + b1[0x1B]; + b2[0x15] = b1[0x15] + b1[0x1A]; + b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4]; + b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5]; + + b2[0x16] = b1[0x16] + b1[0x19]; + b2[0x17] = b1[0x17] + b1[0x18]; + b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6]; + b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7]; + + costab = mpeg3_pnts[2]; + + b1[0x00] = b2[0x00] + b2[0x07]; + b1[0x07] = (b2[0x00] - b2[0x07]) * costab[0]; + b1[0x01] = b2[0x01] + b2[0x06]; + b1[0x06] = (b2[0x01] - b2[0x06]) * costab[1]; + b1[0x02] = b2[0x02] + b2[0x05]; + b1[0x05] = (b2[0x02] - b2[0x05]) * costab[2]; + b1[0x03] = b2[0x03] + b2[0x04]; + b1[0x04] = (b2[0x03] - b2[0x04]) * costab[3]; + + b1[0x08] = b2[0x08] + b2[0x0F]; + b1[0x0F] = (b2[0x0F] - b2[0x08]) * costab[0]; + b1[0x09] = b2[0x09] + b2[0x0E]; + b1[0x0E] = (b2[0x0E] - b2[0x09]) * costab[1]; + b1[0x0A] = b2[0x0A] + b2[0x0D]; + b1[0x0D] = (b2[0x0D] - b2[0x0A]) * costab[2]; + b1[0x0B] = b2[0x0B] + b2[0x0C]; + b1[0x0C] = (b2[0x0C] - b2[0x0B]) * costab[3]; + + b1[0x10] = b2[0x10] + b2[0x17]; + b1[0x17] = (b2[0x10] - b2[0x17]) * costab[0]; + b1[0x11] = b2[0x11] + b2[0x16]; + b1[0x16] = (b2[0x11] - b2[0x16]) * costab[1]; + b1[0x12] = b2[0x12] + b2[0x15]; + b1[0x15] = (b2[0x12] - b2[0x15]) * costab[2]; + b1[0x13] = b2[0x13] + b2[0x14]; + b1[0x14] = (b2[0x13] - b2[0x14]) * costab[3]; + + b1[0x18] = b2[0x18] + b2[0x1F]; + b1[0x1F] = (b2[0x1F] - b2[0x18]) * costab[0]; + b1[0x19] = b2[0x19] + b2[0x1E]; + b1[0x1E] = (b2[0x1E] - b2[0x19]) * costab[1]; + b1[0x1A] = b2[0x1A] + b2[0x1D]; + b1[0x1D] = (b2[0x1D] - b2[0x1A]) * costab[2]; + b1[0x1B] = b2[0x1B] + b2[0x1C]; + b1[0x1C] = (b2[0x1C] - b2[0x1B]) * costab[3]; + + { + register mpeg3_real_t const cos0 = mpeg3_pnts[3][0]; + register mpeg3_real_t const cos1 = mpeg3_pnts[3][1]; + + b2[0x00] = b1[0x00] + b1[0x03]; + b2[0x03] = (b1[0x00] - b1[0x03]) * cos0; + b2[0x01] = b1[0x01] + b1[0x02]; + b2[0x02] = (b1[0x01] - b1[0x02]) * cos1; + + b2[0x04] = b1[0x04] + b1[0x07]; + b2[0x07] = (b1[0x07] - b1[0x04]) * cos0; + b2[0x05] = b1[0x05] + b1[0x06]; + b2[0x06] = (b1[0x06] - b1[0x05]) * cos1; + + b2[0x08] = b1[0x08] + b1[0x0B]; + b2[0x0B] = (b1[0x08] - b1[0x0B]) * cos0; + b2[0x09] = b1[0x09] + b1[0x0A]; + b2[0x0A] = (b1[0x09] - b1[0x0A]) * cos1; + + b2[0x0C] = b1[0x0C] + b1[0x0F]; + b2[0x0F] = (b1[0x0F] - b1[0x0C]) * cos0; + b2[0x0D] = b1[0x0D] + b1[0x0E]; + b2[0x0E] = (b1[0x0E] - b1[0x0D]) * cos1; + + b2[0x10] = b1[0x10] + b1[0x13]; + b2[0x13] = (b1[0x10] - b1[0x13]) * cos0; + b2[0x11] = b1[0x11] + b1[0x12]; + b2[0x12] = (b1[0x11] - b1[0x12]) * cos1; + + b2[0x14] = b1[0x14] + b1[0x17]; + b2[0x17] = (b1[0x17] - b1[0x14]) * cos0; + b2[0x15] = b1[0x15] + b1[0x16]; + b2[0x16] = (b1[0x16] - b1[0x15]) * cos1; + + b2[0x18] = b1[0x18] + b1[0x1B]; + b2[0x1B] = (b1[0x18] - b1[0x1B]) * cos0; + b2[0x19] = b1[0x19] + b1[0x1A]; + b2[0x1A] = (b1[0x19] - b1[0x1A]) * cos1; + + b2[0x1C] = b1[0x1C] + b1[0x1F]; + b2[0x1F] = (b1[0x1F] - b1[0x1C]) * cos0; + b2[0x1D] = b1[0x1D] + b1[0x1E]; + b2[0x1E] = (b1[0x1E] - b1[0x1D]) * cos1; + } + + { + register mpeg3_real_t const cos0 = mpeg3_pnts[4][0]; + + b1[0x00] = b2[0x00] + b2[0x01]; + b1[0x01] = (b2[0x00] - b2[0x01]) * cos0; + b1[0x02] = b2[0x02] + b2[0x03]; + b1[0x03] = (b2[0x03] - b2[0x02]) * cos0; + b1[0x02] += b1[0x03]; + + b1[0x04] = b2[0x04] + b2[0x05]; + b1[0x05] = (b2[0x04] - b2[0x05]) * cos0; + b1[0x06] = b2[0x06] + b2[0x07]; + b1[0x07] = (b2[0x07] - b2[0x06]) * cos0; + b1[0x06] += b1[0x07]; + b1[0x04] += b1[0x06]; + b1[0x06] += b1[0x05]; + b1[0x05] += b1[0x07]; + + b1[0x08] = b2[0x08] + b2[0x09]; + b1[0x09] = (b2[0x08] - b2[0x09]) * cos0; + b1[0x0A] = b2[0x0A] + b2[0x0B]; + b1[0x0B] = (b2[0x0B] - b2[0x0A]) * cos0; + b1[0x0A] += b1[0x0B]; + + b1[0x0C] = b2[0x0C] + b2[0x0D]; + b1[0x0D] = (b2[0x0C] - b2[0x0D]) * cos0; + b1[0x0E] = b2[0x0E] + b2[0x0F]; + b1[0x0F] = (b2[0x0F] - b2[0x0E]) * cos0; + b1[0x0E] += b1[0x0F]; + b1[0x0C] += b1[0x0E]; + b1[0x0E] += b1[0x0D]; + b1[0x0D] += b1[0x0F]; + + b1[0x10] = b2[0x10] + b2[0x11]; + b1[0x11] = (b2[0x10] - b2[0x11]) * cos0; + b1[0x12] = b2[0x12] + b2[0x13]; + b1[0x13] = (b2[0x13] - b2[0x12]) * cos0; + b1[0x12] += b1[0x13]; + + b1[0x14] = b2[0x14] + b2[0x15]; + b1[0x15] = (b2[0x14] - b2[0x15]) * cos0; + b1[0x16] = b2[0x16] + b2[0x17]; + b1[0x17] = (b2[0x17] - b2[0x16]) * cos0; + b1[0x16] += b1[0x17]; + b1[0x14] += b1[0x16]; + b1[0x16] += b1[0x15]; + b1[0x15] += b1[0x17]; + + b1[0x18] = b2[0x18] + b2[0x19]; + b1[0x19] = (b2[0x18] - b2[0x19]) * cos0; + b1[0x1A] = b2[0x1A] + b2[0x1B]; + b1[0x1B] = (b2[0x1B] - b2[0x1A]) * cos0; + b1[0x1A] += b1[0x1B]; + + b1[0x1C] = b2[0x1C] + b2[0x1D]; + b1[0x1D] = (b2[0x1C] - b2[0x1D]) * cos0; + b1[0x1E] = b2[0x1E] + b2[0x1F]; + b1[0x1F] = (b2[0x1F] - b2[0x1E]) * cos0; + b1[0x1E] += b1[0x1F]; + b1[0x1C] += b1[0x1E]; + b1[0x1E] += b1[0x1D]; + b1[0x1D] += b1[0x1F]; + } + + out0[0x10*16] = b1[0x00]; + out0[0x10*12] = b1[0x04]; + out0[0x10* 8] = b1[0x02]; + out0[0x10* 4] = b1[0x06]; + out0[0x10* 0] = b1[0x01]; + out1[0x10* 0] = b1[0x01]; + out1[0x10* 4] = b1[0x05]; + out1[0x10* 8] = b1[0x03]; + out1[0x10*12] = b1[0x07]; + + out0[0x10*14] = b1[0x08] + b1[0x0C]; + out0[0x10*10] = b1[0x0C] + b1[0x0a]; + out0[0x10* 6] = b1[0x0A] + b1[0x0E]; + out0[0x10* 2] = b1[0x0E] + b1[0x09]; + out1[0x10* 2] = b1[0x09] + b1[0x0D]; + out1[0x10* 6] = b1[0x0D] + b1[0x0B]; + out1[0x10*10] = b1[0x0B] + b1[0x0F]; + out1[0x10*14] = b1[0x0F]; + + { + register mpeg3_real_t tmp; + tmp = b1[0x18] + b1[0x1C]; + out0[0x10*15] = tmp + b1[0x10]; + out0[0x10*13] = tmp + b1[0x14]; + tmp = b1[0x1C] + b1[0x1A]; + out0[0x10*11] = tmp + b1[0x14]; + out0[0x10* 9] = tmp + b1[0x12]; + tmp = b1[0x1A] + b1[0x1E]; + out0[0x10* 7] = tmp + b1[0x12]; + out0[0x10* 5] = tmp + b1[0x16]; + tmp = b1[0x1E] + b1[0x19]; + out0[0x10* 3] = tmp + b1[0x16]; + out0[0x10* 1] = tmp + b1[0x11]; + tmp = b1[0x19] + b1[0x1D]; + out1[0x10* 1] = tmp + b1[0x11]; + out1[0x10* 3] = tmp + b1[0x15]; + tmp = b1[0x1D] + b1[0x1B]; + out1[0x10* 5] = tmp + b1[0x15]; + out1[0x10* 7] = tmp + b1[0x13]; + tmp = b1[0x1B] + b1[0x1F]; + out1[0x10* 9] = tmp + b1[0x13]; + out1[0x10*11] = tmp + b1[0x17]; + out1[0x10*13] = b1[0x17] + b1[0x1F]; + out1[0x10*15] = b1[0x1F]; + } + return 0; +} + +/* + * the call via dct64 is a trick to force GCC to use + * (new) registers for the b1,b2 pointer to the bufs[xx] field + */ +int mpeg3audio_dct64(mpeg3_real_t *a, mpeg3_real_t *b, mpeg3_real_t *c) +{ + mpeg3_real_t bufs[0x40]; + return mpeg3audio_dct64_1(a, b, bufs, bufs + 0x20, c); +} + +/*//////////////////////////////////////////////////////////////// */ +/* */ +/* 9 Point Inverse Discrete Cosine Transform */ +/* */ +/* This piece of code is Copyright 1997 Mikko Tommila and is freely usable */ +/* by anybody. The algorithm itself is of course in the public domain. */ +/* */ +/* Again derived heuristically from the 9-point WFTA. */ +/* */ +/* The algorithm is optimized (?) for speed, not for small rounding errors or */ +/* good readability. */ +/* */ +/* 36 additions, 11 multiplications */ +/* */ +/* Again this is very likely sub-optimal. */ +/* */ +/* The code is optimized to use a minimum number of temporary variables, */ +/* so it should compile quite well even on 8-register Intel x86 processors. */ +/* This makes the code quite obfuscated and very difficult to understand. */ +/* */ +/* References: */ +/* [1] S. Winograd: "On Computing the Discrete Fourier Transform", */ +/* Mathematics of Computation, Volume 32, Number 141, January 1978, */ +/* Pages 175-199 */ + + +/*------------------------------------------------------------------*/ +/* */ +/* Function: Calculation of the inverse MDCT */ +/* */ +/*------------------------------------------------------------------*/ + +int mpeg3audio_dct36(mpeg3_real_t *inbuf, mpeg3_real_t *o1, mpeg3_real_t *o2, mpeg3_real_t *wintab, mpeg3_real_t *tsbuf) +{ + mpeg3_real_t tmp[18]; + + { + register mpeg3_real_t *in = inbuf; + + in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14]; + in[14]+=in[13]; in[13]+=in[12]; in[12]+=in[11]; + in[11]+=in[10]; in[10]+=in[9]; in[9] +=in[8]; + in[8] +=in[7]; in[7] +=in[6]; in[6] +=in[5]; + in[5] +=in[4]; in[4] +=in[3]; in[3] +=in[2]; + in[2] +=in[1]; in[1] +=in[0]; + + in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9]; + in[9] +=in[7]; in[7] +=in[5]; in[5] +=in[3]; in[3] +=in[1]; + + + { + mpeg3_real_t t3; + { + mpeg3_real_t t0, t1, t2; + + t0 = mpeg3_COS6_2 * (in[8] + in[16] - in[4]); + t1 = mpeg3_COS6_2 * in[12]; + + t3 = in[0]; + t2 = t3 - t1 - t1; + tmp[1] = tmp[7] = t2 - t0; + tmp[4] = t2 + t0 + t0; + t3 += t1; + + t2 = mpeg3_COS6_1 * (in[10] + in[14] - in[2]); + tmp[1] -= t2; + tmp[7] += t2; + } + { + mpeg3_real_t t0, t1, t2; + + t0 = mpeg3_cos9[0] * (in[4] + in[8] ); + t1 = mpeg3_cos9[1] * (in[8] - in[16]); + t2 = mpeg3_cos9[2] * (in[4] + in[16]); + + tmp[2] = tmp[6] = t3 - t0 - t2; + tmp[0] = tmp[8] = t3 + t0 + t1; + tmp[3] = tmp[5] = t3 - t1 + t2; + } + } + { + mpeg3_real_t t1, t2, t3; + + t1 = mpeg3_cos18[0] * (in[2] + in[10]); + t2 = mpeg3_cos18[1] * (in[10] - in[14]); + t3 = mpeg3_COS6_1 * in[6]; + + { + mpeg3_real_t t0 = t1 + t2 + t3; + tmp[0] += t0; + tmp[8] -= t0; + } + + t2 -= t3; + t1 -= t3; + + t3 = mpeg3_cos18[2] * (in[2] + in[14]); + + t1 += t3; + tmp[3] += t1; + tmp[5] -= t1; + + t2 -= t3; + tmp[2] += t2; + tmp[6] -= t2; + } + + + { + mpeg3_real_t t0, t1, t2, t3, t4, t5, t6, t7; + + t1 = mpeg3_COS6_2 * in[13]; + t2 = mpeg3_COS6_2 * (in[9] + in[17] - in[5]); + + t3 = in[1] + t1; + t4 = in[1] - t1 - t1; + t5 = t4 - t2; + + t0 = mpeg3_cos9[0] * (in[5] + in[9]); + t1 = mpeg3_cos9[1] * (in[9] - in[17]); + + tmp[13] = (t4 + t2 + t2) * mpeg3_tfcos36[17-13]; + t2 = mpeg3_cos9[2] * (in[5] + in[17]); + + t6 = t3 - t0 - t2; + t0 += t3 + t1; + t3 += t2 - t1; + + t2 = mpeg3_cos18[0] * (in[3] + in[11]); + t4 = mpeg3_cos18[1] * (in[11] - in[15]); + t7 = mpeg3_COS6_1 * in[7]; + + t1 = t2 + t4 + t7; + tmp[17] = (t0 + t1) * mpeg3_tfcos36[17-17]; + tmp[9] = (t0 - t1) * mpeg3_tfcos36[17-9]; + t1 = mpeg3_cos18[2] * (in[3] + in[15]); + t2 += t1 - t7; + + tmp[14] = (t3 + t2) * mpeg3_tfcos36[17-14]; + t0 = mpeg3_COS6_1 * (in[11] + in[15] - in[3]); + tmp[12] = (t3 - t2) * mpeg3_tfcos36[17-12]; + + t4 -= t1 + t7; + + tmp[16] = (t5 - t0) * mpeg3_tfcos36[17-16]; + tmp[10] = (t5 + t0) * mpeg3_tfcos36[17-10]; + tmp[15] = (t6 + t4) * mpeg3_tfcos36[17-15]; + tmp[11] = (t6 - t4) * mpeg3_tfcos36[17-11]; + } + +#define MACRO(v) \ + { \ + mpeg3_real_t tmpval; \ + tmpval = tmp[(v)] + tmp[17-(v)]; \ + out2[9+(v)] = tmpval * w[27+(v)]; \ + out2[8-(v)] = tmpval * w[26-(v)]; \ + tmpval = tmp[(v)] - tmp[17-(v)]; \ + ts[SBLIMIT*(8-(v))] = out1[8-(v)] + tmpval * w[8-(v)]; \ + ts[SBLIMIT*(9+(v))] = out1[9+(v)] + tmpval * w[9+(v)]; \ + } + + { + register mpeg3_real_t *out2 = o2; + register mpeg3_real_t *w = wintab; + register mpeg3_real_t *out1 = o1; + register mpeg3_real_t *ts = tsbuf; + + MACRO(0); + MACRO(1); + MACRO(2); + MACRO(3); + MACRO(4); + MACRO(5); + MACRO(6); + MACRO(7); + MACRO(8); + } + } + return 0; +} + +/* + * new DCT12 + */ +int mpeg3audio_dct12(mpeg3_real_t *in,mpeg3_real_t *rawout1,mpeg3_real_t *rawout2,register mpeg3_real_t *wi,register mpeg3_real_t *ts) +{ +#define DCT12_PART1 \ + in5 = in[5*3]; \ + in5 += (in4 = in[4*3]); \ + in4 += (in3 = in[3*3]); \ + in3 += (in2 = in[2*3]); \ + in2 += (in1 = in[1*3]); \ + in1 += (in0 = in[0*3]); \ + \ + in5 += in3; in3 += in1; \ + \ + in2 *= mpeg3_COS6_1; \ + in3 *= mpeg3_COS6_1; \ + +#define DCT12_PART2 \ + in0 += in4 * mpeg3_COS6_2; \ + \ + in4 = in0 + in2; \ + in0 -= in2; \ + \ + in1 += in5 * mpeg3_COS6_2; \ + \ + in5 = (in1 + in3) * mpeg3_tfcos12[0]; \ + in1 = (in1 - in3) * mpeg3_tfcos12[2]; \ + \ + in3 = in4 + in5; \ + in4 -= in5; \ + \ + in2 = in0 + in1; \ + in0 -= in1; + + + { + mpeg3_real_t in0,in1,in2,in3,in4,in5; + register mpeg3_real_t *out1 = rawout1; + ts[SBLIMIT*0] = out1[0]; ts[SBLIMIT*1] = out1[1]; ts[SBLIMIT*2] = out1[2]; + ts[SBLIMIT*3] = out1[3]; ts[SBLIMIT*4] = out1[4]; ts[SBLIMIT*5] = out1[5]; + + DCT12_PART1 + + { + mpeg3_real_t tmp0,tmp1 = (in0 - in4); + { + mpeg3_real_t tmp2 = (in1 - in5) * mpeg3_tfcos12[1]; + tmp0 = tmp1 + tmp2; + tmp1 -= tmp2; + } + ts[(17-1)*SBLIMIT] = out1[17-1] + tmp0 * wi[11-1]; + ts[(12+1)*SBLIMIT] = out1[12+1] + tmp0 * wi[6+1]; + ts[(6 +1)*SBLIMIT] = out1[6 +1] + tmp1 * wi[1]; + ts[(11-1)*SBLIMIT] = out1[11-1] + tmp1 * wi[5-1]; + } + + DCT12_PART2 + + ts[(17-0)*SBLIMIT] = out1[17-0] + in2 * wi[11-0]; + ts[(12+0)*SBLIMIT] = out1[12+0] + in2 * wi[6+0]; + ts[(12+2)*SBLIMIT] = out1[12+2] + in3 * wi[6+2]; + ts[(17-2)*SBLIMIT] = out1[17-2] + in3 * wi[11-2]; + + ts[(6+0)*SBLIMIT] = out1[6+0] + in0 * wi[0]; + ts[(11-0)*SBLIMIT] = out1[11-0] + in0 * wi[5-0]; + ts[(6+2)*SBLIMIT] = out1[6+2] + in4 * wi[2]; + ts[(11-2)*SBLIMIT] = out1[11-2] + in4 * wi[5-2]; + } + + in++; + + { + mpeg3_real_t in0,in1,in2,in3,in4,in5; + register mpeg3_real_t *out2 = rawout2; + + DCT12_PART1 + + { + mpeg3_real_t tmp0,tmp1 = (in0 - in4); + { + mpeg3_real_t tmp2 = (in1 - in5) * mpeg3_tfcos12[1]; + tmp0 = tmp1 + tmp2; + tmp1 -= tmp2; + } + out2[5-1] = tmp0 * wi[11-1]; + out2[0+1] = tmp0 * wi[6+1]; + ts[(12+1)*SBLIMIT] += tmp1 * wi[1]; + ts[(17-1)*SBLIMIT] += tmp1 * wi[5-1]; + } + + DCT12_PART2 + + out2[5-0] = in2 * wi[11-0]; + out2[0+0] = in2 * wi[6+0]; + out2[0+2] = in3 * wi[6+2]; + out2[5-2] = in3 * wi[11-2]; + + ts[(12+0)*SBLIMIT] += in0 * wi[0]; + ts[(17-0)*SBLIMIT] += in0 * wi[5-0]; + ts[(12+2)*SBLIMIT] += in4 * wi[2]; + ts[(17-2)*SBLIMIT] += in4 * wi[5-2]; + } + + in++; + + { + mpeg3_real_t in0,in1,in2,in3,in4,in5; + register mpeg3_real_t *out2 = rawout2; + out2[12]=out2[13]=out2[14]=out2[15]=out2[16]=out2[17]=0.0; + + DCT12_PART1 + + { + mpeg3_real_t tmp0,tmp1 = (in0 - in4); + { + mpeg3_real_t tmp2 = (in1 - in5) * mpeg3_tfcos12[1]; + tmp0 = tmp1 + tmp2; + tmp1 -= tmp2; + } + out2[11-1] = tmp0 * wi[11-1]; + out2[6 +1] = tmp0 * wi[6+1]; + out2[0+1] += tmp1 * wi[1]; + out2[5-1] += tmp1 * wi[5-1]; + } + + DCT12_PART2 + + out2[11-0] = in2 * wi[11-0]; + out2[6 +0] = in2 * wi[6+0]; + out2[6 +2] = in3 * wi[6+2]; + out2[11-2] = in3 * wi[11-2]; + + out2[0+0] += in0 * wi[0]; + out2[5-0] += in0 * wi[5-0]; + out2[0+2] += in4 * wi[2]; + out2[5-2] += in4 * wi[5-2]; + } + return 0; +} + +/* AC3 IMDCT tables */ + +/* Twiddle factors for IMDCT */ +#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES) +static mpeg3_real_t mpeg3_xcos1[AC3_N / 4]; +static mpeg3_real_t mpeg3_xsin1[AC3_N / 4]; +static mpeg3_real_t mpeg3_xcos2[AC3_N / 8]; +static mpeg3_real_t mpeg3_xsin2[AC3_N / 8]; +#else +#define USE_FP_TABLES +#include "fptables.h" +#endif + +/* 128 point bit-reverse LUT */ +static unsigned char mpeg3_bit_reverse_512[] = +{ + 0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70, + 0x08, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78, + 0x04, 0x44, 0x24, 0x64, 0x14, 0x54, 0x34, 0x74, + 0x0c, 0x4c, 0x2c, 0x6c, 0x1c, 0x5c, 0x3c, 0x7c, + 0x02, 0x42, 0x22, 0x62, 0x12, 0x52, 0x32, 0x72, + 0x0a, 0x4a, 0x2a, 0x6a, 0x1a, 0x5a, 0x3a, 0x7a, + 0x06, 0x46, 0x26, 0x66, 0x16, 0x56, 0x36, 0x76, + 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e, + 0x01, 0x41, 0x21, 0x61, 0x11, 0x51, 0x31, 0x71, + 0x09, 0x49, 0x29, 0x69, 0x19, 0x59, 0x39, 0x79, + 0x05, 0x45, 0x25, 0x65, 0x15, 0x55, 0x35, 0x75, + 0x0d, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d, + 0x03, 0x43, 0x23, 0x63, 0x13, 0x53, 0x33, 0x73, + 0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x7b, + 0x07, 0x47, 0x27, 0x67, 0x17, 0x57, 0x37, 0x77, + 0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, 0x7f +}; + +static unsigned char mpeg3_bit_reverse_256[] = +{ + 0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38, + 0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c, + 0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a, + 0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e, + 0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39, + 0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d, + 0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b, + 0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f +}; + +/* Windowing function for Modified DCT - Thank you acroread */ +static mpeg3_real_t mpeg3_window[] = +{ + 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130, + 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443, + 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061, + 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121, + 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770, + 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153, + 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389, + 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563, + 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699, + 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757, + 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626, + 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126, + 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019, + 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031, + 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873, + 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269, + 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981, + 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831, + 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716, + 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610, + 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560, + 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674, + 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099, + 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994, + 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513, + 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788, + 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919, + 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974, + 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993, + 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999, + 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, + 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 +}; + +mpeg3_complex_t cmplx_mult(mpeg3_complex_t a, mpeg3_complex_t b) +{ + mpeg3_complex_t ret; + + ret.real = a.real * b.real - a.imag * b.imag; + ret.imag = a.real * b.imag + a.imag * b.real; + + return ret; +} + +int mpeg3audio_imdct_init(mpeg3audio_t *audio) +{ + int i, k; + mpeg3_complex_t angle_step; + mpeg3_complex_t current_angle; + +/* Twiddle factors to turn IFFT into IMDCT */ + for(i = 0; i < AC3_N / 4; i++) + { + mpeg3_xcos1[i] = -cos(2.0f * M_PI * (8 * i + 1 ) / ( 8 * AC3_N)); + mpeg3_xsin1[i] = -sin(2.0f * M_PI * (8 * i + 1 ) / ( 8 * AC3_N)); + } + +/* More twiddle factors to turn IFFT into IMDCT */ + for(i = 0; i < AC3_N / 8; i++) + { + mpeg3_xcos2[i] = -cos(2.0f * M_PI * (8 * i + 1 ) / ( 4 * AC3_N)); + mpeg3_xsin2[i] = -sin(2.0f * M_PI * (8 * i + 1 ) / ( 4 * AC3_N)); + } + +/* Canonical twiddle factors for FFT */ +#if defined(USE_FIXED_POINT) && !defined(PRINT_FIXED_POINT_TABLES) + for(i = 0; i < 7; i++) + { + audio->ac3_w[i] = (mpeg3_complex_t*)ac3_w_fixedpoints[i]; + } +#else + audio->ac3_w[0] = audio->ac3_w_1; + audio->ac3_w[1] = audio->ac3_w_2; + audio->ac3_w[2] = audio->ac3_w_4; + audio->ac3_w[3] = audio->ac3_w_8; + audio->ac3_w[4] = audio->ac3_w_16; + audio->ac3_w[5] = audio->ac3_w_32; + audio->ac3_w[6] = audio->ac3_w_64; + + for(i = 0; i < 7; i++) + { + angle_step.real = cos(-2.0f * M_PI / (1 << (i + 1))); + angle_step.imag = sin(-2.0f * M_PI / (1 << (i + 1))); + + current_angle.real = 1.0f; + current_angle.imag = 0.0f; + + for (k = 0; k < 1 << i; k++) + { + audio->ac3_w[i][k] = current_angle; + current_angle = cmplx_mult(current_angle, angle_step); + } + } + +#ifdef PRINT_FIXED_POINT_TABLES + printf("#ifdef USE_FP_TABLES\n"); + printf("static long mpeg3_xcos1_fixedpoints[] = {"); + for(i = 0; i < AC3_N / 4; i++) { + printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xcos1[i].fixedPoint()); + } + printf("\n};\nstatic mpeg3_real_t *mpeg3_xcos1 = \n" + "(mpeg3_real_t*)mpeg3_xcos1_fixedpoints;\n"); + + printf("static long mpeg3_xsin1_fixedpoints[] = {"); + for(i = 0; i < AC3_N / 4; i++) { + printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xsin1[i].fixedPoint()); + } + printf("\n};\nstatic mpeg3_real_t *mpeg3_xsin1 = \n" + "(mpeg3_real_t*)mpeg3_xsin1_fixedpoints;\n"); + + + printf("static long mpeg3_xcos2_fixedpoints[] = {"); + for(i = 0; i < AC3_N / 4; i++) { + printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xcos2[i].fixedPoint()); + } + printf("\n};\nstatic mpeg3_real_t *mpeg3_xcos2 = \n" + "(mpeg3_real_t*)mpeg3_xcos2_fixedpoints;\n"); + + printf("static long mpeg3_xsin2_fixedpoints[] = {"); + for(i = 0; i < AC3_N / 4; i++) { + printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xsin2[i].fixedPoint()); + } + printf("\n};\nstatic mpeg3_real_t *mpeg3_xsin2 = \n" + "(mpeg3_real_t*)mpeg3_xsin2_fixedpoints;\n"); + + + printf("typedef struct { long r, i; } fixed_cmplx;\n"); + for(i = 0; i < 7; i++) + { + printf("fixed_cmplx ac3_w_d%d[] = { ", 1<ac3_w[i][k].real.fixedPoint(), + audio->ac3_w[i][k].imag.fixedPoint()); + } + printf("};\n"); + } + + printf("fixed_cmplx *ac3_w_fixedpoints[] = {\n"); + for(i = 0; i < 7; i++) + { + printf("ac3_w_d%d, ", 1<ac3_imdct_buf; + +/* Pre IFFT complex multiply plus IFFT cmplx conjugate */ + for(i = 0; i < AC3_N / 4; i++) + { + buf[i].real = (data[AC3_N / 2 - 2 * i - 1] * mpeg3_xcos1[i]) - (data[2 * i] * mpeg3_xsin1[i]); + buf[i].imag = -((data[2 * i] * mpeg3_xcos1[i]) + (data[AC3_N / 2 - 2 * i - 1] * mpeg3_xsin1[i])); + } + +/* Bit reversed shuffling */ + for(i = 0; i < AC3_N / 4; i++) + { + k = mpeg3_bit_reverse_512[i]; + if(k < i) + swap_cmplx(&buf[i], &buf[k]); + } + +/* FFT Merge */ + for(m = 0; m < 7; m++) + { + if(m) + two_m = (1 << m); + else + two_m = 1; + + two_m_plus_one = (1 << (m + 1)); + + for(k = 0; k < two_m; k++) + { + for(i = 0; i < AC3_N / 4; i += two_m_plus_one) + { + p = k + i; + q = p + two_m; + tmp_a_r = buf[p].real; + tmp_a_i = buf[p].imag; + tmp_b_r = buf[q].real * audio->ac3_w[m][k].real - buf[q].imag * audio->ac3_w[m][k].imag; + tmp_b_i = buf[q].imag * audio->ac3_w[m][k].real + buf[q].real * audio->ac3_w[m][k].imag; + buf[p].real = tmp_a_r + tmp_b_r; + buf[p].imag = tmp_a_i + tmp_b_i; + buf[q].real = tmp_a_r - tmp_b_r; + buf[q].imag = tmp_a_i - tmp_b_i; + } + } + } + +/* Post IFFT complex multiply plus IFFT complex conjugate*/ + for(i = 0; i < AC3_N / 4; i++) + { + tmp_a_r = buf[i].real; + tmp_a_i = -buf[i].imag; + buf[i].real = (tmp_a_r * mpeg3_xcos1[i]) - (tmp_a_i * mpeg3_xsin1[i]); + buf[i].imag = (tmp_a_r * mpeg3_xsin1[i]) + (tmp_a_i * mpeg3_xcos1[i]); + } + + y_ptr = y; + delay_ptr = delay; + window_ptr = mpeg3_window; + +/* Window and convert to real valued signal */ + for(i = 0; i < AC3_N / 8; i++) + { + *y_ptr = -buf[AC3_N / 8 + i].imag * *window_ptr++ + *delay_ptr++; + y_ptr += step; + *y_ptr = buf[AC3_N / 8 - i - 1].real * *window_ptr++ + *delay_ptr++; + y_ptr += step; + } + + for(i = 0; i < AC3_N / 8; i++) + { + *y_ptr = -buf[i].real * *window_ptr++ + *delay_ptr++; + y_ptr += step; + *y_ptr = buf[AC3_N / 4 - i - 1].imag * *window_ptr++ + *delay_ptr++; + y_ptr += step; + } + +/* The trailing edge of the window goes into the delay line */ + delay_ptr = delay; + + for(i = 0; i < AC3_N / 8; i++) + { + *delay_ptr++ = -buf[AC3_N / 8 + i].real * *--window_ptr; + *delay_ptr++ = buf[AC3_N / 8 - i - 1].imag * *--window_ptr; + } + + for(i = 0; i < AC3_N / 8; i++) + { + *delay_ptr++ = buf[i].imag * *--window_ptr; + *delay_ptr++ = -buf[AC3_N / 4 - i - 1].real * *--window_ptr; + } +} + +void mpeg3audio_ac3_imdct_do_256(mpeg3audio_t *audio, + mpeg3_real_t data[], + mpeg3_real_t *y, + int step, + mpeg3_real_t *delay) +{ + int i, k; + int p, q; + int m; + int two_m; + int two_m_plus_one; + mpeg3_complex_t *buf = audio->ac3_imdct_buf; + mpeg3_real_t *y_ptr; + mpeg3_real_t *delay_ptr; + mpeg3_real_t *window_ptr; + + mpeg3_real_t tmp_a_i; + mpeg3_real_t tmp_a_r; + mpeg3_real_t tmp_b_i; + mpeg3_real_t tmp_b_r; + + mpeg3_complex_t *buf_1, *buf_2; + + buf_1 = &buf[0]; + buf_2 = &buf[64]; + +/* Pre IFFT complex multiply plus IFFT cmplx conjugate */ + for(k = 0; k < AC3_N / 8; k++) + { + p = 2 * (AC3_N / 4 - 2 * k - 1); + q = 2 * (2 * k); + + buf_1[k].real = data[p] * mpeg3_xcos2[k] - data[q] * mpeg3_xsin2[k]; + buf_1[k].imag = - (data[q] * mpeg3_xcos2[k] + data[p] * mpeg3_xsin2[k]); + buf_2[k].real = data[p + 1] * mpeg3_xcos2[k] - data[q + 1] * mpeg3_xsin2[k]; + buf_2[k].imag = - (data[q + 1] * mpeg3_xcos2[k] + data[p + 1] * mpeg3_xsin2[k]); + } + +/* IFFT Bit reversed shuffling */ + for(i = 0; i < AC3_N / 8; i++) + { + k = mpeg3_bit_reverse_256[i]; + if(k < i) + { + swap_cmplx(&buf_1[i], &buf_1[k]); + swap_cmplx(&buf_2[i], &buf_2[k]); + } + } + +/* FFT Merge */ + for(m = 0; m < 6; m++) + { + if(m) + two_m = (1 << m); + else + two_m = 1; + + two_m_plus_one = (1 << (m + 1)); + + for(k = 0; k < two_m; k++) + { + for(i = 0; i < AC3_N / 8; i += two_m_plus_one) + { + p = k + i; + q = p + two_m; +/* Do block 1 */ + tmp_a_r = buf_1[p].real; + tmp_a_i = buf_1[p].imag; + tmp_b_r = buf_1[q].real * audio->ac3_w[m][k].real - buf_1[q].imag * audio->ac3_w[m][k].imag; + tmp_b_i = buf_1[q].imag * audio->ac3_w[m][k].real + buf_1[q].real * audio->ac3_w[m][k].imag; + buf_1[p].real = tmp_a_r + tmp_b_r; + buf_1[p].imag = tmp_a_i + tmp_b_i; + buf_1[q].real = tmp_a_r - tmp_b_r; + buf_1[q].imag = tmp_a_i - tmp_b_i; + +/* Do block 2 */ + tmp_a_r = buf_2[p].real; + tmp_a_i = buf_2[p].imag; + tmp_b_r = buf_2[q].real * audio->ac3_w[m][k].real - buf_2[q].imag * audio->ac3_w[m][k].imag; + tmp_b_i = buf_2[q].imag * audio->ac3_w[m][k].real + buf_2[q].real * audio->ac3_w[m][k].imag; + buf_2[p].real = tmp_a_r + tmp_b_r; + buf_2[p].imag = tmp_a_i + tmp_b_i; + buf_2[q].real = tmp_a_r - tmp_b_r; + buf_2[q].imag = tmp_a_i - tmp_b_i; + } + } + } + +/* Post IFFT complex multiply */ + for(i = 0; i < AC3_N / 8; i++) + { + tmp_a_r = buf_1[i].real; + tmp_a_i = -buf_1[i].imag; + buf_1[i].real = (tmp_a_r * mpeg3_xcos2[i]) - (tmp_a_i * mpeg3_xsin2[i]); + buf_1[i].imag = (tmp_a_r * mpeg3_xsin2[i]) + (tmp_a_i * mpeg3_xcos2[i]); + tmp_a_r = buf_2[i].real; + tmp_a_i = -buf_2[i].imag; + buf_2[i].real = (tmp_a_r * mpeg3_xcos2[i]) - (tmp_a_i * mpeg3_xsin2[i]); + buf_2[i].imag = (tmp_a_r * mpeg3_xsin2[i]) + (tmp_a_i * mpeg3_xcos2[i]); + } + +/* Window and convert to real valued signal */ + y_ptr = y; + delay_ptr = delay; + window_ptr = mpeg3_window; + + for(i = 0; i < AC3_N / 8; i++) + { + *y_ptr = -buf[AC3_N / 8 + i].imag * *window_ptr++ + *delay_ptr++; + y_ptr += step; + *y_ptr = buf[AC3_N / 8 - i - 1].real * *window_ptr++ + *delay_ptr++; + y_ptr += step; + } + + for(i = 0; i < AC3_N / 8; i++) + { + *y_ptr = -buf[i].real * *window_ptr++ + *delay_ptr++; + y_ptr += step; + *y_ptr = buf[AC3_N / 4 - i - 1].imag * *window_ptr++ + *delay_ptr++; + y_ptr += step; + } + +/* The trailing edge of the window goes into the delay line */ + delay_ptr = delay; + + for(i = 0; i < AC3_N / 8; i++) + { + *delay_ptr++ = -buf[AC3_N / 8 + i].real * *--window_ptr; + *delay_ptr++ = buf[AC3_N / 8 - i - 1].imag * *--window_ptr; + } + + for(i = 0; i < AC3_N / 8; i++) + { + *delay_ptr++ = buf[i].imag * *--window_ptr; + *delay_ptr++ = -buf[AC3_N / 4 - i - 1].real * *--window_ptr; + } +} + +int mpeg3audio_ac3_imdct(mpeg3audio_t *audio, + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk, + mpeg3ac3_stream_samples_t samples) +{ + int i; + + for(i = 0; i < bsi->nfchans; i++) + { + if(audblk->blksw[i]) + mpeg3audio_ac3_imdct_do_256(audio, + samples[i], + audio->pcm_sample + audio->pcm_point + i, + bsi->nfchans, + audio->ac3_delay[i]); + else + mpeg3audio_ac3_imdct_do_512(audio, + samples[i], + audio->pcm_sample + audio->pcm_point + i, + bsi->nfchans, + audio->ac3_delay[i]); + } + audio->pcm_point += AC3_N / 2 * bsi->nfchans; + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/exponents.c b/core/multimedia/opieplayer/libmpeg3/audio/exponents.c new file mode 100644 index 0000000..deda9b9 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/exponents.c @@ -0,0 +1,141 @@ +/* + * + * exponents.c Copyright (C) Aaron Holtzman - May 1999 + * + * This file is part of libmpeg3 + * + * libmpeg3 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * libmpeg3 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include + +/* Exponent defines */ +#define UNPACK_FBW 1 +#define UNPACK_CPL 2 +#define UNPACK_LFE 4 + +static inline int mpeg3audio_ac3_exp_unpack_ch(unsigned int type, + unsigned int expstr, + unsigned int ngrps, + unsigned int initial_exp, + unsigned short exps[], + unsigned short *dest) +{ + int i, j; + int exp_acc; + int exp_1, exp_2, exp_3; + + if(expstr == MPEG3_EXP_REUSE) + return 0; + +/* Handle the initial absolute exponent */ + exp_acc = initial_exp; + j = 0; + +/* In the case of a fbw channel then the initial absolute value is + * also an exponent */ + if(type != UNPACK_CPL) + dest[j++] = exp_acc; + +/* Loop through the groups and fill the dest array appropriately */ + for(i = 0; i < ngrps; i++) + { + if(exps[i] > 124) + { + fprintf(stderr, "mpeg3audio_ac3_exp_unpack_ch: Invalid exponent %d\n", exps[i]); + return 1; + } + + exp_1 = exps[i] / 25; + exp_2 = (exps[i] % 25) / 5; + exp_3 = (exps[i] % 25) % 5; + + exp_acc += (exp_1 - 2); + + switch(expstr) + { + case MPEG3_EXP_D45: + dest[j++] = exp_acc; + dest[j++] = exp_acc; + case MPEG3_EXP_D25: + dest[j++] = exp_acc; + case MPEG3_EXP_D15: + dest[j++] = exp_acc; + } + + exp_acc += (exp_2 - 2); + + switch(expstr) + { + case MPEG3_EXP_D45: + dest[j++] = exp_acc; + dest[j++] = exp_acc; + case MPEG3_EXP_D25: + dest[j++] = exp_acc; + case MPEG3_EXP_D15: + dest[j++] = exp_acc; + } + + exp_acc += (exp_3 - 2); + + switch(expstr) + { + case MPEG3_EXP_D45: + dest[j++] = exp_acc; + dest[j++] = exp_acc; + case MPEG3_EXP_D25: + dest[j++] = exp_acc; + case MPEG3_EXP_D15: + dest[j++] = exp_acc; + } + } + return 0; +} + +int mpeg3audio_ac3_exponent_unpack(mpeg3audio_t *audio, + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk) +{ + int i, result = 0; + + for(i = 0; i < bsi->nfchans; i++) + result |= mpeg3audio_ac3_exp_unpack_ch(UNPACK_FBW, + audblk->chexpstr[i], + audblk->nchgrps[i], + audblk->exps[i][0], + &audblk->exps[i][1], + audblk->fbw_exp[i]); + + if(audblk->cplinu && !result) + result |= mpeg3audio_ac3_exp_unpack_ch(UNPACK_CPL, + audblk->cplexpstr, + audblk->ncplgrps, + audblk->cplabsexp << 1, + audblk->cplexps, + &audblk->cpl_exp[audblk->cplstrtmant]); + + if(bsi->lfeon && !result) + result |= mpeg3audio_ac3_exp_unpack_ch(UNPACK_LFE, + audblk->lfeexpstr, + 2, + audblk->lfeexps[0], + &audblk->lfeexps[1], + audblk->lfe_exp); + return result; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/fptables.h b/core/multimedia/opieplayer/libmpeg3/audio/fptables.h new file mode 100644 index 0000000..2836984 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/fptables.h @@ -0,0 +1,1556 @@ +#ifdef USE_FP_TABLES +static long mpeg3_xcos1_fixedpoints[] = { +0xffff8001, 0xffff8004, 0xffff800c, 0xffff8019, 0xffff802a, 0xffff8041, 0xffff805d, 0xffff807e, +0xffff80a3, 0xffff80ce, 0xffff80fd, 0xffff8131, 0xffff816b, 0xffff81a9, 0xffff81ec, 0xffff8233, +0xffff8280, 0xffff82d1, 0xffff8328, 0xffff8383, 0xffff83e3, 0xffff8447, 0xffff84b1, 0xffff851f, +0xffff8592, 0xffff860a, 0xffff8686, 0xffff8707, 0xffff878d, 0xffff8817, 0xffff88a6, 0xffff893a, +0xffff89d2, 0xffff8a6f, 0xffff8b10, 0xffff8bb6, 0xffff8c60, 0xffff8d0f, 0xffff8dc2, 0xffff8e7a, +0xffff8f35, 0xffff8ff6, 0xffff90ba, 0xffff9183, 0xffff9250, 0xffff9322, 0xffff93f7, 0xffff94d1, +0xffff95af, 0xffff9691, 0xffff9777, 0xffff9861, 0xffff994f, 0xffff9a41, 0xffff9b37, 0xffff9c31, +0xffff9d2e, 0xffff9e30, 0xffff9f35, 0xffffa03e, 0xffffa14b, 0xffffa25b, 0xffffa36f, 0xffffa487, +0xffffa5a2, 0xffffa6c0, 0xffffa7e2, 0xffffa907, 0xffffaa30, 0xffffab5c, 0xffffac8b, 0xffffadbe, +0xffffaef4, 0xffffb02c, 0xffffb168, 0xffffb2a7, 0xffffb3e9, 0xffffb52e, 0xffffb676, 0xffffb7c0, +0xffffb90d, 0xffffba5d, 0xffffbbb0, 0xffffbd06, 0xffffbe5e, 0xffffbfb8, 0xffffc115, 0xffffc274, +0xffffc3d6, 0xffffc53a, 0xffffc6a1, 0xffffc809, 0xffffc974, 0xffffcae1, 0xffffcc50, 0xffffcdc0, +0xffffcf33, 0xffffd0a8, 0xffffd21e, 0xffffd397, 0xffffd511, 0xffffd68c, 0xffffd80a, 0xffffd988, +0xffffdb09, 0xffffdc8a, 0xffffde0d, 0xffffdf92, 0xffffe117, 0xffffe29e, 0xffffe426, 0xffffe5af, +0xffffe739, 0xffffe8c4, 0xffffea50, 0xffffebdd, 0xffffed6a, 0xffffeef8, 0xfffff087, 0xfffff217, +0xfffff3a7, 0xfffff537, 0xfffff6c8, 0xfffff859, 0xfffff9eb, 0xfffffb7d, 0xfffffd0f, 0xfffffea1, +}; +static mpeg3_real_t *mpeg3_xcos1 = +(mpeg3_real_t*)mpeg3_xcos1_fixedpoints; +static long mpeg3_xsin1_fixedpoints[] = { +0xffffffce, 0xfffffe3c, 0xfffffcaa, 0xfffffb18, 0xfffff986, 0xfffff7f5, 0xfffff664, 0xfffff4d3, +0xfffff343, 0xfffff1b3, 0xfffff023, 0xffffee95, 0xffffed07, 0xffffeb79, 0xffffe9ed, 0xffffe861, +0xffffe6d6, 0xffffe54d, 0xffffe3c4, 0xffffe23c, 0xffffe0b6, 0xffffdf30, 0xffffddac, 0xffffdc2a, +0xffffdaa8, 0xffffd928, 0xffffd7aa, 0xffffd62d, 0xffffd4b2, 0xffffd338, 0xffffd1c1, 0xffffd04b, +0xffffced6, 0xffffcd64, 0xffffcbf4, 0xffffca85, 0xffffc919, 0xffffc7af, 0xffffc647, 0xffffc4e1, +0xffffc37d, 0xffffc21c, 0xffffc0bd, 0xffffbf61, 0xffffbe07, 0xffffbcb0, 0xffffbb5b, 0xffffba09, +0xffffb8ba, 0xffffb76d, 0xffffb623, 0xffffb4dc, 0xffffb398, 0xffffb257, 0xffffb119, 0xffffafde, +0xffffaea6, 0xffffad71, 0xffffac3f, 0xffffab11, 0xffffa9e6, 0xffffa8be, 0xffffa799, 0xffffa678, +0xffffa55b, 0xffffa440, 0xffffa32a, 0xffffa217, 0xffffa107, 0xffff9ffc, 0xffff9ef3, 0xffff9def, +0xffff9cef, 0xffff9bf2, 0xffff9af9, 0xffff9a04, 0xffff9913, 0xffff9826, 0xffff973d, 0xffff9658, +0xffff9577, 0xffff949a, 0xffff93c1, 0xffff92ed, 0xffff921d, 0xffff9151, 0xffff9089, 0xffff8fc5, +0xffff8f06, 0xffff8e4b, 0xffff8d95, 0xffff8ce3, 0xffff8c35, 0xffff8b8c, 0xffff8ae7, 0xffff8a47, +0xffff89ac, 0xffff8915, 0xffff8882, 0xffff87f4, 0xffff876b, 0xffff86e7, 0xffff8667, 0xffff85eb, +0xffff8575, 0xffff8503, 0xffff8496, 0xffff842e, 0xffff83ca, 0xffff836c, 0xffff8312, 0xffff82bd, +0xffff826c, 0xffff8221, 0xffff81da, 0xffff8199, 0xffff815c, 0xffff8124, 0xffff80f1, 0xffff80c3, +0xffff8099, 0xffff8075, 0xffff8056, 0xffff803b, 0xffff8026, 0xffff8015, 0xffff8009, 0xffff8002, +}; +static mpeg3_real_t *mpeg3_xsin1 = +(mpeg3_real_t*)mpeg3_xsin1_fixedpoints; +static long mpeg3_xcos2_fixedpoints[] = { +0xffff8001, 0xffff800d, 0xffff802d, 0xffff8061, 0xffff80a8, 0xffff8103, 0xffff8172, 0xffff81f4, +0xffff828a, 0xffff8333, 0xffff83ef, 0xffff84be, 0xffff85a1, 0xffff8696, 0xffff879e, 0xffff88b9, +0xffff89e5, 0xffff8b25, 0xffff8c76, 0xffff8dd9, 0xffff8f4d, 0xffff90d3, 0xffff926a, 0xffff9412, +0xffff95cb, 0xffff9794, 0xffff996d, 0xffff9b56, 0xffff9d4e, 0xffff9f56, 0xffffa16d, 0xffffa392, +0xffffa5c5, 0xffffa807, 0xffffaa55, 0xffffacb2, 0xffffaf1b, 0xffffb190, 0xffffb411, 0xffffb69f, +0xffffb937, 0xffffbbdb, 0xffffbe89, 0xffffc141, 0xffffc403, 0xffffc6ce, 0xffffc9a1, 0xffffcc7e, +0xffffcf62, 0xffffd24d, 0xffffd540, 0xffffd839, 0xffffdb39, 0xffffde3e, 0xffffe148, 0xffffe457, +0xffffe76a, 0xffffea81, 0xffffed9c, 0xfffff0b9, 0xfffff3d9, 0xfffff6fa, 0xfffffa1d, 0xfffffd41, +0xffffff9c, 0xfffffc78, 0xfffff954, 0xfffff632, 0xfffff311, 0xffffeff2, 0xffffecd5, 0xffffe9bb, +0xffffe6a5, 0xffffe393, 0xffffe085, 0xffffdd7c, 0xffffda78, 0xffffd77a, 0xffffd483, 0xffffd192, +0xffffcea8, 0xffffcbc6, 0xffffc8ec, 0xffffc61a, 0xffffc351, 0xffffc092, 0xffffbddc, 0xffffbb31, +0xffffb890, 0xffffb5fa, 0xffffb370, 0xffffb0f1, 0xffffae7f, 0xffffac19, 0xffffa9c0, 0xffffa775, +0xffffa537, 0xffffa307, 0xffffa0e6, 0xffff9ed3, 0xffff9ccf, 0xffff9ada, 0xffff98f5, 0xffff9720, +0xffff955b, 0xffff93a7, 0xffff9203, 0xffff9070, 0xffff8eee, 0xffff8d7e, 0xffff8c20, 0xffff8ad3, +0xffff8998, 0xffff8870, 0xffff875a, 0xffff8657, 0xffff8566, 0xffff8489, 0xffff83be, 0xffff8307, +0xffff8263, 0xffff81d2, 0xffff8155, 0xffff80eb, 0xffff8095, 0xffff8052, 0xffff8023, 0xffff8008, +}; +static mpeg3_real_t *mpeg3_xcos2 = +(mpeg3_real_t*)mpeg3_xcos2_fixedpoints; +static long mpeg3_xsin2_fixedpoints[] = { +0xffffff9c, 0xfffffc78, 0xfffff954, 0xfffff632, 0xfffff311, 0xffffeff2, 0xffffecd5, 0xffffe9bb, +0xffffe6a5, 0xffffe393, 0xffffe085, 0xffffdd7c, 0xffffda78, 0xffffd77a, 0xffffd483, 0xffffd192, +0xffffcea8, 0xffffcbc6, 0xffffc8ec, 0xffffc61a, 0xffffc351, 0xffffc092, 0xffffbddc, 0xffffbb31, +0xffffb890, 0xffffb5fa, 0xffffb370, 0xffffb0f1, 0xffffae7f, 0xffffac19, 0xffffa9c0, 0xffffa775, +0xffffa537, 0xffffa307, 0xffffa0e6, 0xffff9ed3, 0xffff9ccf, 0xffff9ada, 0xffff98f5, 0xffff9720, +0xffff955b, 0xffff93a7, 0xffff9203, 0xffff9070, 0xffff8eee, 0xffff8d7e, 0xffff8c20, 0xffff8ad3, +0xffff8998, 0xffff8870, 0xffff875a, 0xffff8657, 0xffff8566, 0xffff8489, 0xffff83be, 0xffff8307, +0xffff8263, 0xffff81d2, 0xffff8155, 0xffff80eb, 0xffff8095, 0xffff8052, 0xffff8023, 0xffff8008, +0x00000004, 0x00000007, 0x0000000c, 0x00000010, 0x00000015, 0x0000001c, 0x00000023, 0x0000002a, +0x00000033, 0x0000003d, 0x00000048, 0x00000053, 0x00000061, 0x0000006f, 0x0000007f, 0x00000091, +0x000000a4, 0x000000b8, 0x000000cf, 0x000000e7, 0x00000101, 0x0000011d, 0x0000013b, 0x0000015b, +0x0000017e, 0x000001a3, 0x000001ca, 0x000001f4, 0x00000220, 0x0000024f, 0x00000281, 0x000002b7, +0x000002ef, 0x0000032a, 0x00000368, 0x000003aa, 0x000003ee, 0x00000437, 0x00000483, 0x000004d3, +0x00000526, 0x0000057e, 0x000005d9, 0x00000639, 0x0000069c, 0x00000704, 0x0000076f, 0x000007e0, +0x00000854, 0x000008cd, 0x0000094b, 0x000009cd, 0x00000a54, 0x00000adf, 0x00000b6f, 0x00000c04, +0x00000c9e, 0x00000d3d, 0x00000de0, 0x00000e89, 0x00000f36, 0x00000fe8, 0x0000109f, 0x0000115c, +}; +static mpeg3_real_t *mpeg3_xsin2 = +(mpeg3_real_t*)mpeg3_xsin2_fixedpoints; +typedef struct { long r, i; } fixed_cmplx; +fixed_cmplx ac3_w_d1[] = { + { 0x00008000, 0x00000000 },}; +fixed_cmplx ac3_w_d2[] = { + { 0x00008000, 0x00000000 }, { 0x00000000, 0xffff8000 },}; +fixed_cmplx ac3_w_d4[] = { + { 0x00008000, 0x00000000 }, { 0x00005a82, 0xffffa57e }, { 0x00000000, 0xffff8002 }, { 0xffffa580, 0xffffa580 },}; +fixed_cmplx ac3_w_d8[] = { + { 0x00008000, 0x00000000 }, { 0x00007641, 0xffffcf05 }, { 0x00005a81, 0xffffa580 }, { 0x000030fb, 0xffff89c4 }, + { 0x00000002, 0xffff8007 }, { 0xffffcf09, 0xffff89c6 }, { 0xffffa587, 0xffffa583 }, { 0xffff89cb, 0xffffcf05 },}; +fixed_cmplx ac3_w_d16[] = { + { 0x00008000, 0x00000000 }, { 0x00007d8a, 0xffffe708 }, { 0x00007642, 0xffffcf06 }, { 0x00006a6e, 0xffffb8e7 }, + { 0x00005a84, 0xffffa583 }, { 0x00004720, 0xffff9599 }, { 0x00003100, 0xffff89c6 }, { 0x000018ff, 0xffff827e }, + { 0x00000008, 0xffff8008 }, { 0xffffe711, 0xffff827d }, { 0xffffcf11, 0xffff89c4 }, { 0xffffb8f2, 0xffff9595 }, + { 0xffffa58e, 0xffffa57d }, { 0xffff95a5, 0xffffb8df }, { 0xffff89d2, 0xffffcefd }, { 0xffff8289, 0xffffe6fc },}; +fixed_cmplx ac3_w_d32[] = { + { 0x00008000, 0x00000000 }, { 0x00007f62, 0xfffff375 }, { 0x00007d8a, 0xffffe70a }, { 0x00007a7d, 0xffffdadc }, + { 0x00007642, 0xffffcf0a }, { 0x000070e4, 0xffffc3b1 }, { 0x00006a70, 0xffffb8ed }, { 0x000062f6, 0xffffaed7 }, + { 0x00005a88, 0xffffa58a }, { 0x0000513b, 0xffff9d1b }, { 0x00004726, 0xffff95a1 }, { 0x00003c62, 0xffff8f2d }, + { 0x00003109, 0xffff89cf }, { 0x00002538, 0xffff8593 }, { 0x0000190b, 0xffff8286 }, { 0x00000ca1, 0xffff80ad }, + { 0x00000017, 0xffff800f }, { 0xfffff38d, 0xffff80ab }, { 0xffffe723, 0xffff8281 }, { 0xffffdaf6, 0xffff858b }, + { 0xffffcf25, 0xffff89c4 }, { 0xffffc3cc, 0xffff8f1f }, { 0xffffb908, 0xffff9591 }, { 0xffffaef3, 0xffff9d09 }, + { 0xffffa5a6, 0xffffa575 }, { 0xffff9d37, 0xffffaebf }, { 0xffff95bb, 0xffffb8d2 }, { 0xffff8f46, 0xffffc393 }, + { 0xffff89e7, 0xffffcee9 }, { 0xffff85aa, 0xffffdab8 }, { 0xffff829b, 0xffffe6e3 }, { 0xffff80c1, 0xfffff34b },}; +fixed_cmplx ac3_w_d64[] = { + { 0x00008000, 0x00000000 }, { 0x00007fd8, 0xfffff9b9 }, { 0x00007f62, 0xfffff376 }, { 0x00007e9d, 0xffffed3b }, + { 0x00007d8a, 0xffffe70c }, { 0x00007c29, 0xffffe0ec }, { 0x00007a7c, 0xffffdae0 }, { 0x00007883, 0xffffd4eb }, + { 0x00007641, 0xffffcf11 }, { 0x000073b6, 0xffffc955 }, { 0x000070e3, 0xffffc3bb }, { 0x00006dcb, 0xffffbe45 }, + { 0x00006a6f, 0xffffb8f8 }, { 0x000066d2, 0xffffb3d7 }, { 0x000062f5, 0xffffaee5 }, { 0x00005edc, 0xffffaa25 }, + { 0x00005a89, 0xffffa59a }, { 0x000055fe, 0xffffa147 }, { 0x0000513e, 0xffff9d2e }, { 0x00004c4c, 0xffff9952 }, + { 0x0000472b, 0xffff95b6 }, { 0x000041de, 0xffff925b }, { 0x00003c69, 0xffff8f44 }, { 0x000036cf, 0xffff8c72 }, + { 0x00003113, 0xffff89e7 }, { 0x00002b39, 0xffff87a4 }, { 0x00002544, 0xffff85ac }, { 0x00001f39, 0xffff8400 }, + { 0x0000191b, 0xffff82a0 }, { 0x000012ed, 0xffff818d }, { 0x00000cb4, 0xffff80c8 }, { 0x00000673, 0xffff8051 }, + { 0x0000002d, 0xffff8029 }, { 0xfffff9e8, 0xffff804f }, { 0xfffff3a7, 0xffff80c3 }, { 0xffffed6e, 0xffff8186 }, + { 0xffffe741, 0xffff8297 }, { 0xffffe123, 0xffff83f5 }, { 0xffffdb18, 0xffff859f }, { 0xffffd524, 0xffff8795 }, + { 0xffffcf4b, 0xffff89d5 }, { 0xffffc990, 0xffff8c5d }, { 0xffffc3f7, 0xffff8f2d }, { 0xffffbe82, 0xffff9242 }, + { 0xffffb936, 0xffff959b }, { 0xffffb416, 0xffff9935 }, { 0xffffaf24, 0xffff9d0f }, { 0xffffaa64, 0xffffa125 }, + { 0xffffa5d9, 0xffffa575 }, { 0xffffa186, 0xffffa9fd }, { 0xffff9d6d, 0xffffaeba }, { 0xffff9990, 0xffffb3a9 }, + { 0xffff95f3, 0xffffb8c7 }, { 0xffff9297, 0xffffbe11 }, { 0xffff8f7f, 0xffffc383 }, { 0xffff8cac, 0xffffc91a }, + { 0xffff8a20, 0xffffced3 }, { 0xffff87dc, 0xffffd4aa }, { 0xffff85e2, 0xffffda9c }, { 0xffff8434, 0xffffe0a5 }, + { 0xffff82d2, 0xffffe6c1 }, { 0xffff81be, 0xffffecec }, { 0xffff80f7, 0xfffff323 }, { 0xffff807e, 0xfffff962 },}; +fixed_cmplx *ac3_w_fixedpoints[] = { +ac3_w_d1, ac3_w_d2, ac3_w_d4, ac3_w_d8, ac3_w_d16, ac3_w_d32, ac3_w_d64, }; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_muls_data[] = { +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffff5556, 0xffff788b, 0xffff947d, 0xffffaaab, 0xffffbc46, 0xffffca3f, 0xffffd556, 0xffffde23, +0xffffe520, 0xffffeaab, 0xffffef12, 0xfffff290, 0xfffff556, 0xfffff789, 0xfffff948, 0xfffffaab, +0xfffffbc5, 0xfffffca4, 0xfffffd56, 0xfffffde3, 0xfffffe52, 0xfffffeab, 0xfffffef2, 0xffffff29, +0xffffff56, 0xffffff79, 0xffffff95, 0xffffffab, 0xffffffbd, 0xffffffcb, 0xffffffd6, 0xffffffdf, +0xffffffe6, 0xffffffeb, 0xfffffff0, 0xfffffff3, 0xfffffff6, 0xfffffff8, 0xfffffffa, 0xfffffffb, +0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x0000aaaa, 0x00008775, 0x00006b83, 0x00005555, 0x000043ba, 0x000035c1, 0x00002aaa, 0x000021dd, +0x00001ae0, 0x00001555, 0x000010ee, 0x00000d70, 0x00000aaa, 0x00000877, 0x000006b8, 0x00000555, +0x0000043b, 0x0000035c, 0x000002aa, 0x0000021d, 0x000001ae, 0x00000155, 0x0000010e, 0x000000d7, +0x000000aa, 0x00000087, 0x0000006b, 0x00000055, 0x00000043, 0x00000035, 0x0000002a, 0x00000021, +0x0000001a, 0x00000015, 0x00000010, 0x0000000d, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, +0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00004924, 0x00003a0d, 0x00002e13, 0x00002492, 0x00001d06, 0x00001709, 0x00001249, 0x00000e83, +0x00000b84, 0x00000924, 0x00000741, 0x000005c2, 0x00000492, 0x000003a0, 0x000002e1, 0x00000249, +0x000001d0, 0x00000170, 0x00000124, 0x000000e8, 0x000000b8, 0x00000092, 0x00000074, 0x0000005c, +0x00000049, 0x0000003a, 0x0000002e, 0x00000024, 0x0000001d, 0x00000017, 0x00000012, 0x0000000e, +0x0000000b, 0x00000009, 0x00000007, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, +0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00002222, 0x00001b17, 0x00001580, 0x00001111, 0x00000d8b, 0x00000ac0, 0x00000888, 0x000006c5, +0x00000560, 0x00000444, 0x00000362, 0x000002b0, 0x00000222, 0x000001b1, 0x00000158, 0x00000111, +0x000000d8, 0x000000ac, 0x00000088, 0x0000006c, 0x00000056, 0x00000044, 0x00000036, 0x0000002b, +0x00000022, 0x0000001b, 0x00000015, 0x00000011, 0x0000000d, 0x0000000a, 0x00000008, 0x00000006, +0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00001084, 0x00000d1b, 0x00000a67, 0x00000842, 0x0000068d, 0x00000533, 0x00000421, 0x00000346, +0x00000299, 0x00000210, 0x000001a3, 0x0000014c, 0x00000108, 0x000000d1, 0x000000a6, 0x00000084, +0x00000068, 0x00000053, 0x00000042, 0x00000034, 0x00000029, 0x00000021, 0x0000001a, 0x00000014, +0x00000010, 0x0000000d, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, +0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000820, 0x00000673, 0x0000051e, 0x00000410, 0x00000339, 0x0000028f, 0x00000208, 0x0000019c, +0x00000147, 0x00000104, 0x000000ce, 0x000000a3, 0x00000082, 0x00000067, 0x00000051, 0x00000041, +0x00000033, 0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, +0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, +0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000408, 0x00000333, 0x0000028a, 0x00000204, 0x00000199, 0x00000145, 0x00000102, 0x000000cc, +0x000000a2, 0x00000081, 0x00000066, 0x00000051, 0x00000040, 0x00000033, 0x00000028, 0x00000020, +0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, +0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000202, 0x00000197, 0x00000143, 0x00000101, 0x000000cb, 0x000000a1, 0x00000080, 0x00000065, +0x00000050, 0x00000040, 0x00000032, 0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, +0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, +0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000100, 0x000000cb, 0x000000a1, 0x00000080, 0x00000065, 0x00000050, 0x00000040, 0x00000032, +0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, +0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, +0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000080, 0x00000065, 0x00000050, 0x00000040, 0x00000032, 0x00000028, 0x00000020, 0x00000019, +0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, +0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000040, 0x00000032, 0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, +0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, +0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, +0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, +0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, +0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffff3334, 0xffff5d74, 0xffff7efc, 0xffff999a, 0xffffaeba, 0xffffbf7e, 0xffffcccd, 0xffffd75d, +0xffffdfbf, 0xffffe667, 0xffffebaf, 0xffffefe0, 0xfffff334, 0xfffff5d8, 0xfffff7f0, 0xfffff99a, +0xfffffaec, 0xfffffbf8, 0xfffffccd, 0xfffffd76, 0xfffffdfc, 0xfffffe67, 0xfffffebb, 0xfffffefe, +0xffffff34, 0xffffff5e, 0xffffff7f, 0xffffff9a, 0xffffffaf, 0xffffffc0, 0xffffffcd, 0xffffffd8, +0xffffffe0, 0xffffffe7, 0xffffffec, 0xfffffff0, 0xfffffff4, 0xfffffff6, 0xfffffff8, 0xfffffffa, +0xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffff999a, 0xffffaeba, 0xffffbf7e, 0xffffcccd, 0xffffd75d, 0xffffdfbf, 0xffffe667, 0xffffebaf, +0xffffefe0, 0xfffff334, 0xfffff5d8, 0xfffff7f0, 0xfffff99a, 0xfffffaec, 0xfffffbf8, 0xfffffccd, +0xfffffd76, 0xfffffdfc, 0xfffffe67, 0xfffffebb, 0xfffffefe, 0xffffff34, 0xffffff5e, 0xffffff7f, +0xffffff9a, 0xffffffaf, 0xffffffc0, 0xffffffcd, 0xffffffd8, 0xffffffe0, 0xffffffe7, 0xffffffec, +0xfffffff0, 0xfffffff4, 0xfffffff6, 0xfffffff8, 0xfffffffa, 0xfffffffb, 0xfffffffc, 0xfffffffd, +0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00006666, 0x00005146, 0x00004082, 0x00003333, 0x000028a3, 0x00002041, 0x00001999, 0x00001451, +0x00001020, 0x00000ccc, 0x00000a28, 0x00000810, 0x00000666, 0x00000514, 0x00000408, 0x00000333, +0x0000028a, 0x00000204, 0x00000199, 0x00000145, 0x00000102, 0x000000cc, 0x000000a2, 0x00000081, +0x00000066, 0x00000051, 0x00000040, 0x00000033, 0x00000028, 0x00000020, 0x00000019, 0x00000014, +0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, +0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x0000cccc, 0x0000a28c, 0x00008104, 0x00006666, 0x00005146, 0x00004082, 0x00003333, 0x000028a3, +0x00002041, 0x00001999, 0x00001451, 0x00001020, 0x00000ccc, 0x00000a28, 0x00000810, 0x00000666, +0x00000514, 0x00000408, 0x00000333, 0x0000028a, 0x00000204, 0x00000199, 0x00000145, 0x00000102, +0x000000cc, 0x000000a2, 0x00000081, 0x00000066, 0x00000051, 0x00000040, 0x00000033, 0x00000028, +0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, +0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffff1c72, 0xffff4b64, 0xffff70a7, 0xffff8e39, 0xffffa5b2, 0xffffb854, 0xffffc71d, 0xffffd2d9, +0xffffdc2a, 0xffffe38f, 0xffffe96d, 0xffffee15, 0xfffff1c8, 0xfffff4b7, 0xfffff70b, 0xfffff8e4, +0xfffffa5c, 0xfffffb86, 0xfffffc72, 0xfffffd2e, 0xfffffdc3, 0xfffffe39, 0xfffffe97, 0xfffffee2, +0xffffff1d, 0xffffff4c, 0xffffff71, 0xffffff8f, 0xffffffa6, 0xffffffb9, 0xffffffc8, 0xffffffd3, +0xffffffdd, 0xffffffe4, 0xffffffea, 0xffffffef, 0xfffffff2, 0xfffffff5, 0xfffffff8, 0xfffffff9, +0xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffff8e39, 0xffffa5b2, 0xffffb854, 0xffffc71d, 0xffffd2d9, 0xffffdc2a, 0xffffe38f, 0xffffe96d, +0xffffee15, 0xfffff1c8, 0xfffff4b7, 0xfffff70b, 0xfffff8e4, 0xfffffa5c, 0xfffffb86, 0xfffffc72, +0xfffffd2e, 0xfffffdc3, 0xfffffe39, 0xfffffe97, 0xfffffee2, 0xffffff1d, 0xffffff4c, 0xffffff71, +0xffffff8f, 0xffffffa6, 0xffffffb9, 0xffffffc8, 0xffffffd3, 0xffffffdd, 0xffffffe4, 0xffffffea, +0xffffffef, 0xfffffff2, 0xfffffff5, 0xfffffff8, 0xfffffff9, 0xfffffffb, 0xfffffffc, 0xfffffffd, +0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffffc71d, 0xffffd2d9, 0xffffdc2a, 0xffffe38f, 0xffffe96d, 0xffffee15, 0xfffff1c8, 0xfffff4b7, +0xfffff70b, 0xfffff8e4, 0xfffffa5c, 0xfffffb86, 0xfffffc72, 0xfffffd2e, 0xfffffdc3, 0xfffffe39, +0xfffffe97, 0xfffffee2, 0xffffff1d, 0xffffff4c, 0xffffff71, 0xffffff8f, 0xffffffa6, 0xffffffb9, +0xffffffc8, 0xffffffd3, 0xffffffdd, 0xffffffe4, 0xffffffea, 0xffffffef, 0xfffffff2, 0xfffffff5, +0xfffffff8, 0xfffffff9, 0xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, +0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x000038e3, 0x00002d27, 0x000023d6, 0x00001c71, 0x00001693, 0x000011eb, 0x00000e38, 0x00000b49, +0x000008f5, 0x0000071c, 0x000005a4, 0x0000047a, 0x0000038e, 0x000002d2, 0x0000023d, 0x000001c7, +0x00000169, 0x0000011e, 0x000000e3, 0x000000b4, 0x0000008f, 0x00000071, 0x0000005a, 0x00000047, +0x00000038, 0x0000002d, 0x00000023, 0x0000001c, 0x00000016, 0x00000011, 0x0000000e, 0x0000000b, +0x00000008, 0x00000007, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, +0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x000071c7, 0x00005a4e, 0x000047ac, 0x000038e3, 0x00002d27, 0x000023d6, 0x00001c71, 0x00001693, +0x000011eb, 0x00000e38, 0x00000b49, 0x000008f5, 0x0000071c, 0x000005a4, 0x0000047a, 0x0000038e, +0x000002d2, 0x0000023d, 0x000001c7, 0x00000169, 0x0000011e, 0x000000e3, 0x000000b4, 0x0000008f, +0x00000071, 0x0000005a, 0x00000047, 0x00000038, 0x0000002d, 0x00000023, 0x0000001c, 0x00000016, +0x00000011, 0x0000000e, 0x0000000b, 0x00000008, 0x00000007, 0x00000005, 0x00000004, 0x00000003, +0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x0000e38e, 0x0000b49c, 0x00008f59, 0x000071c7, 0x00005a4e, 0x000047ac, 0x000038e3, 0x00002d27, +0x000023d6, 0x00001c71, 0x00001693, 0x000011eb, 0x00000e38, 0x00000b49, 0x000008f5, 0x0000071c, +0x000005a4, 0x0000047a, 0x0000038e, 0x000002d2, 0x0000023d, 0x000001c7, 0x00000169, 0x0000011e, +0x000000e3, 0x000000b4, 0x0000008f, 0x00000071, 0x0000005a, 0x00000047, 0x00000038, 0x0000002d, +0x00000023, 0x0000001c, 0x00000016, 0x00000011, 0x0000000e, 0x0000000b, 0x00000008, 0x00000007, +0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_gainpow2_data[] = { +0x05a82799, 0x04c1bf82, 0x04000000, 0x035d13f3, 0x02d413cc, 0x0260dfc1, 0x02000000, 0x01ae89f9, +0x016a09e6, 0x01306fe0, 0x01000000, 0x00d744fc, 0x00b504f3, 0x009837f0, 0x00800000, 0x006ba27e, +0x005a8279, 0x004c1bf8, 0x00400000, 0x0035d13f, 0x002d413c, 0x00260dfc, 0x00200000, 0x001ae89f, +0x0016a09e, 0x001306fe, 0x00100000, 0x000d744f, 0x000b504f, 0x0009837f, 0x00080000, 0x0006ba27, +0x0005a827, 0x0004c1bf, 0x00040000, 0x00035d13, 0x0002d413, 0x000260df, 0x00020000, 0x0001ae89, +0x00016a09, 0x0001306f, 0x00010000, 0x0000d744, 0x0000b504, 0x00009837, 0x00008000, 0x00006ba2, +0x00005a82, 0x00004c1b, 0x00004000, 0x000035d1, 0x00002d41, 0x0000260d, 0x00002000, 0x00001ae8, +0x000016a0, 0x00001306, 0x00001000, 0x00000d74, 0x00000b50, 0x00000983, 0x00000800, 0x000006ba, +0x000005a8, 0x000004c1, 0x00000400, 0x0000035d, 0x000002d4, 0x00000260, 0x00000200, 0x000001ae, +0x0000016a, 0x00000130, 0x00000100, 0x000000d7, 0x000000b5, 0x00000098, 0x00000080, 0x0000006b, +0x0000005a, 0x0000004c, 0x00000040, 0x00000035, 0x0000002d, 0x00000026, 0x00000020, 0x0000001a, +0x00000016, 0x00000013, 0x00000010, 0x0000000d, 0x0000000b, 0x00000009, 0x00000008, 0x00000006, +0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000001, +0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_ispow_data[] = { +0x00000000, 0x00008000, 0x0001428a, 0x000229d2, 0x00032cbf, 0x00044662, 0x0005738c, 0x0006b1fc, +0x0007ffff, 0x00095c41, 0x000ac5ad, 0x000c3b5d, 0x000dbc8f, 0x000f489e, 0x0010def9, 0x00127f20, +0x001428a2, 0x0015db1b, 0x00179630, 0x0019598d, 0x001b24e8, 0x001cf7fc, 0x001ed28a, 0x0020b458, +0x00229d2e, 0x00248cdb, 0x0026832f, 0x00287fff, 0x002a8322, 0x002c8c70, 0x002e9bc5, 0x0030b0ff, +0x0032cbfd, 0x0034eca0, 0x003712ca, 0x00393e60, 0x003b6f47, 0x003da567, 0x003fe0a5, 0x004220ed, +0x00446627, 0x0046b03e, 0x0048ff1e, 0x004b52b3, 0x004daaeb, 0x005007b4, 0x005268fc, 0x0054ceb2, +0x005738c7, 0x0059a72a, 0x005c19cd, 0x005e90a1, 0x00610b98, 0x00638aa4, 0x00660db9, 0x006894c9, +0x006b1fc8, 0x006daeaa, 0x00704163, 0x0072d7e8, 0x0075722e, 0x0078102b, 0x007ab1d3, 0x007d571e, +0x007fffff, 0x0082ac70, 0x00855c65, 0x00880fd6, 0x008ac6b9, 0x008d8107, 0x00903eb7, 0x0092ffc0, +0x0095c41a, 0x00988bbe, 0x009b56a4, 0x009e24c4, 0x00a0f617, 0x00a3ca96, 0x00a6a239, 0x00a97cfa, +0x00ac5ad2, 0x00af3bbb, 0x00b21fad, 0x00b506a3, 0x00b7f096, 0x00badd81, 0x00bdcd5d, 0x00c0c025, +0x00c3b5d2, 0x00c6ae60, 0x00c9a9c8, 0x00cca805, 0x00cfa912, 0x00d2acea, 0x00d5b387, 0x00d8bce5, +0x00dbc8fe, 0x00ded7ce, 0x00e1e950, 0x00e4fd7e, 0x00e81456, 0x00eb2dd1, 0x00ee49ec, 0x00f168a2, +0x00f489ef, 0x00f7adce, 0x00fad43c, 0x00fdfd34, 0x010128b2, 0x010456b2, 0x01078731, 0x010aba29, +0x010def99, 0x0111277b, 0x011461cc, 0x01179e89, 0x011addae, 0x011e1f37, 0x01216320, 0x0124a967, +0x0127f208, 0x012b3d00, 0x012e8a4b, 0x0131d9e6, 0x01352bce, 0x01387fff, 0x013bd678, 0x013f2f33, +0x01428a2f, 0x0145e768, 0x014946dc, 0x014ca888, 0x01500c68, 0x01537279, 0x0156daba, 0x015a4527, +0x015db1bd, 0x0161207a, 0x0164915b, 0x0168045d, 0x016b797e, 0x016ef0bb, 0x01726a12, 0x0175e580, +0x01796302, 0x017ce297, 0x0180643b, 0x0183e7ec, 0x01876da9, 0x018af56e, 0x018e7f38, 0x01920b07, +0x019598d8, 0x019928a8, 0x019cba74, 0x01a04e3c, 0x01a3e3fd, 0x01a77bb4, 0x01ab155f, 0x01aeb0fd, +0x01b24e8b, 0x01b5ee07, 0x01b98f70, 0x01bd32c2, 0x01c0d7fc, 0x01c47f1d, 0x01c82821, 0x01cbd308, +0x01cf7fcf, 0x01d32e74, 0x01d6def6, 0x01da9153, 0x01de4588, 0x01e1fb94, 0x01e5b375, 0x01e96d29, +0x01ed28af, 0x01f0e604, 0x01f4a528, 0x01f86617, 0x01fc28d2, 0x01ffed55, 0x0203b39f, 0x02077baf, +0x020b4582, 0x020f1118, 0x0212de6e, 0x0216ad83, 0x021a7e56, 0x021e50e4, 0x0222252d, 0x0225fb2e, +0x0229d2e6, 0x022dac54, 0x02318776, 0x0235644b, 0x023942d1, 0x023d2306, 0x024104e9, 0x0244e879, +0x0248cdb5, 0x024cb49a, 0x02509d28, 0x0254875c, 0x02587337, 0x025c60b5, 0x02604fd7, 0x0264409a, +0x026832fd, 0x026c26ff, 0x02701c9f, 0x027413db, 0x02780cb1, 0x027c0722, 0x0280032a, 0x028400ca, +0x0287ffff, 0x028c00ca, 0x02900327, 0x02940716, 0x02980c97, 0x029c13a7, 0x02a01c45, 0x02a42670, +0x02a83228, 0x02ac3f6a, 0x02b04e36, 0x02b45e8b, 0x02b87067, 0x02bc83c9, 0x02c098b1, 0x02c4af1c, +0x02c8c70a, 0x02cce07a, 0x02d0fb6a, 0x02d517da, 0x02d935c9, 0x02dd5534, 0x02e1761c, 0x02e59880, +0x02e9bc5d, 0x02ede1b3, 0x02f20882, 0x02f630c8, 0x02fa5a83, 0x02fe85b4, 0x0302b258, 0x0306e070, +0x030b0ff9, 0x030f40f3, 0x0313735e, 0x0317a737, 0x031bdc7e, 0x03201333, 0x03244b53, 0x032884de, +0x032cbfd4, 0x0330fc33, 0x033539fa, 0x03397929, 0x033db9be, 0x0341fbb8, 0x03463f17, 0x034a83da, +0x034eca00, 0x03531187, 0x03575a6f, 0x035ba4b8, 0x035ff060, 0x03643d66, 0x03688bc9, 0x036cdb8a, +0x03712ca6, 0x03757f1d, 0x0379d2ee, 0x037e2818, 0x03827e9a, 0x0386d674, 0x038b2fa5, 0x038f8a2c, +0x0393e608, 0x03984338, 0x039ca1bc, 0x03a10192, 0x03a562ba, 0x03a9c533, 0x03ae28fd, 0x03b28e16, +0x03b6f47e, 0x03bb5c33, 0x03bfc536, 0x03c42f85, 0x03c89b20, 0x03cd0806, 0x03d17636, 0x03d5e5af, +0x03da5671, 0x03dec87b, 0x03e33bcc, 0x03e7b063, 0x03ec2640, 0x03f09d62, 0x03f515c9, 0x03f98f73, +0x03fe0a5f, 0x0402868e, 0x040703fe, 0x040b82af, 0x041002a0, 0x041483d1, 0x04190640, 0x041d89ec, +0x04220ed7, 0x042694fd, 0x042b1c60, 0x042fa4fe, 0x04342ed6, 0x0438b9e9, 0x043d4635, 0x0441d3b9, +0x04466275, 0x044af269, 0x044f8393, 0x045415f3, 0x0458a988, 0x045d3e53, 0x0461d451, 0x04666b83, +0x046b03e7, 0x046f9d7e, 0x04743846, 0x0478d440, 0x047d716a, 0x04820fc3, 0x0486af4c, 0x048b5003, +0x048ff1e8, 0x049494fa, 0x04993939, 0x049ddea5, 0x04a2853c, 0x04a72cfd, 0x04abd5ea, 0x04b07fff, +0x04b52b3f, 0x04b9d7a6, 0x04be8536, 0x04c333ee, 0x04c7e3cc, 0x04cc94d1, 0x04d146fb, 0x04d5fa4b, +0x04daaebf, 0x04df6458, 0x04e41b14, 0x04e8d2f3, 0x04ed8bf5, 0x04f24618, 0x04f7015d, 0x04fbbdc3, +0x05007b49, 0x050539ef, 0x0509f9b4, 0x050eba98, 0x05137c9a, 0x05183fba, 0x051d03f6, 0x0521c950, +0x05268fc6, 0x052b5757, 0x05302003, 0x0534e9ca, 0x0539b4ab, 0x053e80a5, 0x05434db9, 0x05481be5, +0x054ceb29, 0x0551bb85, 0x05568cf8, 0x055b5f81, 0x05603321, 0x056507d6, 0x0569dda0, 0x056eb47f, +0x05738c72, 0x05786578, 0x057d3f92, 0x05821abe, 0x0586f6fd, 0x058bd44e, 0x0590b2af, 0x05959222, +0x059a72a5, 0x059f5438, 0x05a436da, 0x05a91a8c, 0x05adff4b, 0x05b2e519, 0x05b7cbf5, 0x05bcb3dd, +0x05c19cd3, 0x05c686d4, 0x05cb71e2, 0x05d05dfb, 0x05d54b1f, 0x05da394d, 0x05df2885, 0x05e418c7, +0x05e90a12, 0x05edfc66, 0x05f2efc2, 0x05f7e426, 0x05fcd992, 0x0601d004, 0x0606c77d, 0x060bbffd, +0x0610b982, 0x0615b40c, 0x061aaf9b, 0x061fac2f, 0x0624a9c7, 0x0629a863, 0x062ea802, 0x0633a8a3, +0x0638aa47, 0x063dacee, 0x0642b095, 0x0647b53f, 0x064cbae8, 0x0651c193, 0x0656c93d, 0x065bd1e7, +0x0660db90, 0x0665e639, 0x066af1df, 0x066ffe84, 0x06750c26, 0x067a1ac6, 0x067f2a62, 0x06843afb, +0x06894c90, 0x068e5f21, 0x069372ad, 0x06988735, 0x069d9cb6, 0x06a2b332, 0x06a7caa8, 0x06ace318, +0x06b1fc80, 0x06b716e2, 0x06bc323b, 0x06c14e8d, 0x06c66bd6, 0x06cb8a17, 0x06d0a94e, 0x06d5c97c, +0x06daeaa0, 0x06e00cba, 0x06e52fca, 0x06ea53ce, 0x06ef78c8, 0x06f49eb5, 0x06f9c597, 0x06feed6d, +0x07041635, 0x07093ff1, 0x070e6aa0, 0x07139640, 0x0718c2d3, 0x071df057, 0x07231ecd, 0x07284e33, +0x072d7e8a, 0x0732afd2, 0x0737e209, 0x073d1530, 0x07424946, 0x07477e4a, 0x074cb43e, 0x0751eb20, +0x075722ef, 0x075c5bac, 0x07619556, 0x0766cfee, 0x076c0b71, 0x077147e1, 0x0776853d, 0x077bc385, +0x078102b8, 0x078642d6, 0x078b83de, 0x0790c5d1, 0x079608ae, 0x079b4c74, 0x07a09124, 0x07a5d6bd, +0x07ab1d3e, 0x07b064a8, 0x07b5acfa, 0x07baf634, 0x07c04056, 0x07c58b5e, 0x07cad74e, 0x07d02424, +0x07d571e0, 0x07dac082, 0x07e0100a, 0x07e56077, 0x07eab1ca, 0x07f00401, 0x07f5571c, 0x07faab1c, +0x07ffffff, 0x080555c7, 0x080aac71, 0x081003fe, 0x08155c6e, 0x081ab5c0, 0x08200ff5, 0x08256b0b, +0x082ac703, 0x083023dc, 0x08358196, 0x083ae030, 0x08403fab, 0x0845a006, 0x084b0141, 0x0850635b, +0x0855c654, 0x085b2a2d, 0x08608ee4, 0x0865f479, 0x086b5aed, 0x0870c23e, 0x08762a6d, 0x087b9379, +0x0880fd62, 0x08866828, 0x088bd3ca, 0x08914048, 0x0896ada3, 0x089c1bd8, 0x08a18aea, 0x08a6fad6, +0x08ac6b9d, 0x08b1dd3f, 0x08b74fbb, 0x08bcc311, 0x08c23741, 0x08c7ac4a, 0x08cd222c, 0x08d298e8, +0x08d8107c, 0x08dd88e8, 0x08e3022d, 0x08e87c49, 0x08edf73d, 0x08f37309, 0x08f8efac, 0x08fe6d25, +0x0903eb75, 0x09096a9c, 0x090eea99, 0x09146b6b, 0x0919ed13, 0x091f6f91, 0x0924f2e3, 0x092a770b, +0x092ffc06, 0x093581d7, 0x093b087b, 0x09408ff3, 0x0946183f, 0x094ba15e, 0x09512b51, 0x0956b616, +0x095c41ae, 0x0961ce18, 0x09675b54, 0x096ce962, 0x09727842, 0x097807f3, 0x097d9876, 0x098329c9, +0x0988bbed, 0x098e4ee1, 0x0993e2a6, 0x0999773a, 0x099f0c9f, 0x09a4a2d3, 0x09aa39d6, 0x09afd1a8, +0x09b56a49, 0x09bb03b8, 0x09c09df6, 0x09c63902, 0x09cbd4dc, 0x09d17183, 0x09d70ef8, 0x09dcad3a, +0x09e24c49, 0x09e7ec25, 0x09ed8ccd, 0x09f32e41, 0x09f8d082, 0x09fe738e, 0x0a041766, 0x0a09bc09, +0x0a0f6178, 0x0a1507b1, 0x0a1aaeb5, 0x0a205684, 0x0a25ff1c, 0x0a2ba87f, 0x0a3152ac, 0x0a36fda2, +0x0a3ca962, 0x0a4255ea, 0x0a48033c, 0x0a4db157, 0x0a536039, 0x0a590fe5, 0x0a5ec058, 0x0a647193, +0x0a6a2396, 0x0a6fd660, 0x0a7589f2, 0x0a7b3e4b, 0x0a80f36a, 0x0a86a950, 0x0a8c5ffc, 0x0a92176f, +0x0a97cfa7, 0x0a9d88a5, 0x0aa34269, 0x0aa8fcf2, 0x0aaeb840, 0x0ab47453, 0x0aba312b, 0x0abfeec8, +0x0ac5ad28, 0x0acb6c4d, 0x0ad12c36, 0x0ad6ece2, 0x0adcae52, 0x0ae27085, 0x0ae8337b, 0x0aedf734, +0x0af3bbb0, 0x0af980ee, 0x0aff46ef, 0x0b050db2, 0x0b0ad536, 0x0b109d7c, 0x0b166684, 0x0b1c304d, +0x0b21fad7, 0x0b27c622, 0x0b2d922e, 0x0b335efa, 0x0b392c87, 0x0b3efad3, 0x0b44c9e0, 0x0b4a99ac, +0x0b506a38, 0x0b563b83, 0x0b5c0d8e, 0x0b61e057, 0x0b67b3df, 0x0b6d8826, 0x0b735d2b, 0x0b7932ee, +0x0b7f096f, 0x0b84e0ae, 0x0b8ab8ab, 0x0b909165, 0x0b966add, 0x0b9c4511, 0x0ba22003, 0x0ba7fbb1, +0x0badd81b, 0x0bb3b542, 0x0bb99326, 0x0bbf71c5, 0x0bc55120, 0x0bcb3136, 0x0bd11208, 0x0bd6f395, +0x0bdcd5dd, 0x0be2b8e0, 0x0be89c9e, 0x0bee8116, 0x0bf46649, 0x0bfa4c36, 0x0c0032dc, 0x0c061a3d, +0x0c0c0257, 0x0c11eb2a, 0x0c17d4b7, 0x0c1dbefd, 0x0c23a9fc, 0x0c2995b3, 0x0c2f8223, 0x0c356f4c, +0x0c3b5d2c, 0x0c414bc5, 0x0c473b16, 0x0c4d2b1e, 0x0c531bde, 0x0c590d55, 0x0c5eff83, 0x0c64f268, +0x0c6ae604, 0x0c70da57, 0x0c76cf60, 0x0c7cc51f, 0x0c82bb95, 0x0c88b2c1, 0x0c8eaaa2, 0x0c94a339, +0x0c9a9c85, 0x0ca09687, 0x0ca6913e, 0x0cac8caa, 0x0cb288ca, 0x0cb885a0, 0x0cbe8329, 0x0cc48167, +0x0cca8059, 0x0cd07fff, 0x0cd68059, 0x0cdc8167, 0x0ce28328, 0x0ce8859c, 0x0cee88c4, 0x0cf48c9e, +0x0cfa912b, 0x0d00966b, 0x0d069c5d, 0x0d0ca302, 0x0d12aa59, 0x0d18b262, 0x0d1ebb1d, 0x0d24c489, +0x0d2acea7, 0x0d30d976, 0x0d36e4f7, 0x0d3cf128, 0x0d42fe0b, 0x0d490b9e, 0x0d4f19e2, 0x0d5528d6, +0x0d5b387b, 0x0d6148cf, 0x0d6759d4, 0x0d6d6b88, 0x0d737dec, 0x0d799100, 0x0d7fa4c3, 0x0d85b935, +0x0d8bce56, 0x0d91e426, 0x0d97faa4, 0x0d9e11d1, 0x0da429ad, 0x0daa4237, 0x0db05b6f, 0x0db67555, +0x0dbc8fe9, 0x0dc2ab2a, 0x0dc8c719, 0x0dcee3b5, 0x0dd500ff, 0x0ddb1ef5, 0x0de13d99, 0x0de75ce9, +0x0ded7ce6, 0x0df39d8f, 0x0df9bee5, 0x0dffe0e7, 0x0e060394, 0x0e0c26ee, 0x0e124af4, 0x0e186fa5, +0x0e1e9501, 0x0e24bb09, 0x0e2ae1bb, 0x0e310919, 0x0e373122, 0x0e3d59d5, 0x0e438333, 0x0e49ad3c, +0x0e4fd7ee, 0x0e56034b, 0x0e5c2f52, 0x0e625c02, 0x0e68895d, 0x0e6eb761, 0x0e74e60e, 0x0e7b1564, +0x0e814564, 0x0e87760d, 0x0e8da75e, 0x0e93d959, 0x0e9a0bfb, 0x0ea03f47, 0x0ea6733a, 0x0eaca7d6, +0x0eb2dd1a, 0x0eb91305, 0x0ebf4999, 0x0ec580d4, 0x0ecbb8b6, 0x0ed1f140, 0x0ed82a71, 0x0ede6449, +0x0ee49ec8, 0x0eead9ed, 0x0ef115ba, 0x0ef7522d, 0x0efd8f46, 0x0f03cd05, 0x0f0a0b6b, 0x0f104a76, +0x0f168a28, 0x0f1cca7f, 0x0f230b7b, 0x0f294d1d, 0x0f2f8f65, 0x0f35d251, 0x0f3c15e3, 0x0f425a19, +0x0f489ef4, 0x0f4ee474, 0x0f552a98, 0x0f5b7161, 0x0f61b8ce, 0x0f6800df, 0x0f6e4994, 0x0f7492ed, +0x0f7adce9, 0x0f81278a, 0x0f8772cd, 0x0f8dbeb4, 0x0f940b3e, 0x0f9a586b, 0x0fa0a63c, 0x0fa6f4af, +0x0fad43c4, 0x0fb3937c, 0x0fb9e3d7, 0x0fc034d4, 0x0fc68673, 0x0fccd8b4, 0x0fd32b97, 0x0fd97f1c, +0x0fdfd343, 0x0fe6280b, 0x0fec7d74, 0x0ff2d37f, 0x0ff92a2b, 0x0fff8178, 0x1005d966, 0x100c31f5, +0x10128b24, 0x1018e4f4, 0x101f3f64, 0x10259a75, 0x102bf626, 0x10325277, 0x1038af67, 0x103f0cf8, +0x10456b28, 0x104bc9f8, 0x10522967, 0x10588976, 0x105eea24, 0x10654b70, 0x106bad5c, 0x10720fe7, +0x10787310, 0x107ed6d8, 0x10853b3f, 0x108ba043, 0x109205e6, 0x10986c27, 0x109ed307, 0x10a53a83, +0x10aba29e, 0x10b20b57, 0x10b874ac, 0x10bedea0, 0x10c54930, 0x10cbb45e, 0x10d22029, 0x10d88c90, +0x10def995, 0x10e56736, 0x10ebd574, 0x10f2444e, 0x10f8b3c5, 0x10ff23d8, 0x11059487, 0x110c05d2, +0x111277b9, 0x1118ea3b, 0x111f5d59, 0x1125d113, 0x112c4568, 0x1132ba59, 0x11392fe5, 0x113fa60c, +0x11461ccd, 0x114c942a, 0x11530c22, 0x115984b4, 0x115ffde0, 0x116677a7, 0x116cf209, 0x11736d04, +0x1179e89a, 0x118064c9, 0x1186e192, 0x118d5ef5, 0x1193dcf2, 0x119a5b88, 0x11a0dab8, 0x11a75a81, +0x11addae3, 0x11b45bde, 0x11badd72, 0x11c15f9f, 0x11c7e265, 0x11ce65c4, 0x11d4e9bb, 0x11db6e4a, +0x11e1f372, 0x11e87931, 0x11eeff89, 0x11f58679, 0x11fc0e01, 0x12029621, 0x12091ed8, 0x120fa827, +0x1216320d, 0x121cbc8a, 0x1223479f, 0x1229d34b, 0x12305f8e, 0x1236ec68, 0x123d79d9, 0x124407e0, +0x124a967e, 0x125125b2, 0x1257b57d, 0x125e45de, 0x1264d6d6, 0x126b6863, 0x1271fa86, 0x12788d40, +0x127f208f, 0x1285b473, 0x128c48ed, 0x1292ddfd, 0x129973a2, 0x12a009dc, 0x12a6a0ab, 0x12ad3810, +0x12b3d009, 0x12ba6897, 0x12c101ba, 0x12c79b71, 0x12ce35bd, 0x12d4d09e, 0x12db6c13, 0x12e2081b, +0x12e8a4b9, 0x12ef41ea, 0x12f5dfaf, 0x12fc7e07, 0x13031cf4, 0x1309bc74, 0x13105c88, 0x1316fd2f, +0x131d9e69, 0x13244036, 0x132ae297, 0x1331858b, 0x13382911, 0x133ecd2b, 0x134571d7, 0x134c1716, +0x1352bce7, 0x1359634a, 0x13600a40, 0x1366b1c9, 0x136d59e3, 0x1374028f, 0x137aabce, 0x1381559e, +0x1387ffff, 0x138eaaf3, 0x13955678, 0x139c028e, 0x13a2af36, 0x13a95c6f, 0x13b00a39, 0x13b6b895, +0x13bd6781, 0x13c416fe, 0x13cac70c, 0x13d177aa, 0x13d828d9, 0x13deda99, 0x13e58ce9, 0x13ec3fc9, +0x13f2f33a, 0x13f9a73a, 0x14005bcb, 0x140710eb, 0x140dc69c, 0x14147cdc, 0x141b33ab, 0x1421eb0a, +0x1428a2f9, 0x142f5b77, 0x14361484, 0x143cce21, 0x1443884c, 0x144a4307, 0x1450fe50, 0x1457ba28, +0x145e768f, 0x14653384, 0x146bf108, 0x1472af1b, 0x14796dbb, 0x14802cea, 0x1486eca8, 0x148dacf3, +0x14946dcc, 0x149b2f33, 0x14a1f128, 0x14a8b3aa, 0x14af76ba, 0x14b63a58, 0x14bcfe83, 0x14c3c33b, +0x14ca8881, 0x14d14e54, 0x14d814b4, 0x14dedba0, 0x14e5a31a, 0x14ec6b21, 0x14f333b4, 0x14f9fcd4, +0x1500c680, 0x150790b9, 0x150e5b7e, 0x151526cf, 0x151bf2ad, 0x1522bf17, 0x15298c0c, 0x1530598e, +0x1537279b, 0x153df634, 0x1544c559, 0x154b950a, 0x15526545, 0x1559360d, 0x1560075f, 0x1566d93d, +0x156daba6, 0x15747e99, 0x157b5218, 0x15822622, 0x1588fab6, 0x158fcfd6, 0x1596a57f, 0x159d7bb4, +0x15a45272, 0x15ab29bc, 0x15b2018f, 0x15b8d9ed, 0x15bfb2d4, 0x15c68c46, 0x15cd6641, 0x15d440c7, +0x15db1bd6, 0x15e1f76f, 0x15e8d391, 0x15efb03d, 0x15f68d73, 0x15fd6b31, 0x16044979, 0x160b284a, +0x161207a5, 0x1618e788, 0x161fc7f4, 0x1626a8e9, 0x162d8a67, 0x16346c6d, 0x163b4efc, 0x16423213, +0x164915b3, 0x164ff9dc, 0x1656de8c, 0x165dc3c5, 0x1664a985, 0x166b8fce, 0x1672769f, 0x16795df7, +0x168045d8, 0x16872e40, 0x168e172f, 0x169500a7, 0x169beaa5, 0x16a2d52b, 0x16a9c038, 0x16b0abcd, +0x16b797e8, 0x16be848b, 0x16c571b4, 0x16cc5f65, 0x16d34d9c, 0x16da3c5a, 0x16e12b9e, 0x16e81b69, +0x16ef0bbb, 0x16f5fc93, 0x16fcedf1, 0x1703dfd6, 0x170ad241, 0x1711c531, 0x1718b8a8, 0x171faca5, +0x1726a127, 0x172d9630, 0x17348bbe, 0x173b81d1, 0x1742786b, 0x17496f89, 0x1750672d, 0x17575f56, +0x175e5805, 0x17655139, 0x176c4af1, 0x1773452f, 0x177a3ff2, 0x17813b39, 0x17883705, 0x178f3356, +0x1796302c, 0x179d2d86, 0x17a42b64, 0x17ab29c7, 0x17b228ae, 0x17b92819, 0x17c02809, 0x17c7287c, +0x17ce2974, 0x17d52aef, 0x17dc2cef, 0x17e32f72, 0x17ea3278, 0x17f13603, 0x17f83a11, 0x17ff3ea2, +0x180643b7, 0x180d494f, 0x18144f6a, 0x181b5609, 0x18225d2a, 0x182964cf, 0x18306cf6, 0x183775a1, +0x183e7ece, 0x1845887e, 0x184c92b0, 0x18539d65, 0x185aa89d, 0x1861b457, 0x1868c093, 0x186fcd52, +0x1876da93, 0x187de856, 0x1884f69b, 0x188c0562, 0x189314aa, 0x189a2475, 0x18a134c2, 0x18a84590, +0x18af56e0, 0x18b668b1, 0x18bd7b04, 0x18c48dd8, 0x18cba12d, 0x18d2b504, 0x18d9c95c, 0x18e0de35, +0x18e7f38f, 0x18ef096b, 0x18f61fc7, 0x18fd36a3, 0x19044e01, 0x190b65df, 0x19127e3e, 0x1919971d, +0x1920b07d, 0x1927ca5d, 0x192ee4be, 0x1935ff9f, 0x193d1b00, 0x194436e1, 0x194b5342, 0x19527023, +0x19598d84, 0x1960ab65, 0x1967c9c6, 0x196ee8a6, 0x19760806, 0x197d27e6, 0x19844845, 0x198b6923, +0x19928a81, 0x1999ac5e, 0x19a0ceba, 0x19a7f196, 0x19af14f0, 0x19b638ca, 0x19bd5d22, 0x19c481f9, +0x19cba74f, 0x19d2cd24, 0x19d9f378, 0x19e11a4a, 0x19e8419a, 0x19ef6969, 0x19f691b6, 0x19fdba82, +0x1a04e3cc, 0x1a0c0d94, 0x1a1337da, 0x1a1a629f, 0x1a218de1, 0x1a28b9a1, 0x1a2fe5df, 0x1a37129b, +0x1a3e3fd4, 0x1a456d8b, 0x1a4c9bc0, 0x1a53ca72, 0x1a5af9a2, 0x1a62294f, 0x1a695979, 0x1a708a21, +0x1a77bb45, 0x1a7eece7, 0x1a861f06, 0x1a8d51a2, 0x1a9484bb, 0x1a9bb850, 0x1aa2ec62, 0x1aaa20f1, +0x1ab155fd, 0x1ab88b85, 0x1abfc18a, 0x1ac6f80b, 0x1ace2f09, 0x1ad56683, 0x1adc9e79, 0x1ae3d6eb, +0x1aeb0fda, 0x1af24944, 0x1af9832b, 0x1b00bd8d, 0x1b07f86c, 0x1b0f33c6, 0x1b166f9c, 0x1b1dabed, +0x1b24e8ba, 0x1b2c2603, 0x1b3363c7, 0x1b3aa206, 0x1b41e0c1, 0x1b491ff7, 0x1b505fa9, 0x1b579fd5, +0x1b5ee07d, 0x1b66219f, 0x1b6d633d, 0x1b74a555, 0x1b7be7e9, 0x1b832af7, 0x1b8a6e7f, 0x1b91b283, +0x1b98f701, 0x1ba03bf9, 0x1ba7816c, 0x1baec75a, 0x1bb60dc1, 0x1bbd54a3, 0x1bc49bff, 0x1bcbe3d6, +0x1bd32c26, 0x1bda74f1, 0x1be1be35, 0x1be907f3, 0x1bf0522b, 0x1bf79cdd, 0x1bfee809, 0x1c0633ae, +0x1c0d7fcc, 0x1c14cc65, 0x1c1c1976, 0x1c236702, 0x1c2ab506, 0x1c320384, 0x1c39527b, 0x1c40a1eb, +0x1c47f1d4, 0x1c4f4236, 0x1c569311, 0x1c5de466, 0x1c653632, 0x1c6c8878, 0x1c73db37, 0x1c7b2e6e, +0x1c82821d, 0x1c89d646, 0x1c912ae6, 0x1c987fff, 0x1c9fd591, 0x1ca72b9b, 0x1cae821d, 0x1cb5d917, +0x1cbd3089, 0x1cc48874, 0x1ccbe0d6, 0x1cd339b1, 0x1cda9303, 0x1ce1eccd, 0x1ce9470f, 0x1cf0a1c8, +0x1cf7fcf9, 0x1cff58a2, 0x1d06b4c2, 0x1d0e115a, 0x1d156e69, 0x1d1ccbf0, 0x1d2429ed, 0x1d2b8862, +0x1d32e74e, 0x1d3a46b2, 0x1d41a68c, 0x1d4906dd, 0x1d5067a6, 0x1d57c8e5, 0x1d5f2a9b, 0x1d668cc7, +0x1d6def6b, 0x1d755285, 0x1d7cb615, 0x1d841a1c, 0x1d8b7e9a, 0x1d92e38e, 0x1d9a48f9, 0x1da1aed9, +0x1da91530, 0x1db07bfd, 0x1db7e340, 0x1dbf4afa, 0x1dc6b329, 0x1dce1bce, 0x1dd584e9, 0x1ddcee7a, +0x1de45881, 0x1debc2fe, 0x1df32df0, 0x1dfa9957, 0x1e020535, 0x1e097187, 0x1e10de50, 0x1e184b8d, +0x1e1fb940, 0x1e272768, 0x1e2e9606, 0x1e360518, 0x1e3d74a0, 0x1e44e49d, 0x1e4c550e, 0x1e53c5f5, +0x1e5b3750, 0x1e62a921, 0x1e6a1b66, 0x1e718e20, 0x1e79014e, 0x1e8074f1, 0x1e87e909, 0x1e8f5d95, +0x1e96d295, 0x1e9e480a, 0x1ea5bdf3, 0x1ead3450, 0x1eb4ab22, 0x1ebc2268, 0x1ec39a22, 0x1ecb1250, +0x1ed28af1, 0x1eda0407, 0x1ee17d91, 0x1ee8f78f, 0x1ef07200, 0x1ef7ece5, 0x1eff683d, 0x1f06e40a, +0x1f0e604a, 0x1f15dcfd, 0x1f1d5a24, 0x1f24d7be, 0x1f2c55cb, 0x1f33d44c, 0x1f3b5340, 0x1f42d2a7, +0x1f4a5281, 0x1f51d2ce, 0x1f59538f, 0x1f60d4c2, 0x1f685668, 0x1f6fd881, 0x1f775b0d, 0x1f7ede0c, +0x1f86617d, 0x1f8de561, 0x1f9569b7, 0x1f9cee80, 0x1fa473bb, 0x1fabf969, 0x1fb37f8a, 0x1fbb061c, +0x1fc28d21, 0x1fca1498, 0x1fd19c81, 0x1fd924dc, 0x1fe0ada9, 0x1fe836e9, 0x1fefc09a, 0x1ff74abd, +0x1ffed552, 0x20066059, 0x200debd1, 0x201577bc, 0x201d0417, 0x202490e5, 0x202c1e24, 0x2033abd4, +0x203b39f6, 0x2042c889, 0x204a578d, 0x2051e703, 0x205976ea, 0x20610742, 0x2068980b, 0x20702946, +0x2077baf1, 0x207f4d0d, 0x2086df9a, 0x208e7298, 0x20960607, 0x209d99e7, 0x20a52e37, 0x20acc2f8, +0x20b45829, 0x20bbedcb, 0x20c383de, 0x20cb1a61, 0x20d2b154, 0x20da48b8, 0x20e1e08c, 0x20e978d0, +0x20f11185, 0x20f8aaa9, 0x2100443e, 0x2107de43, 0x210f78b7, 0x2117139c, 0x211eaef0, 0x21264ab5, +0x212de6e9, 0x2135838d, 0x213d20a0, 0x2144be24, 0x214c5c16, 0x2153fa79, 0x215b994b, 0x2163388c, +0x216ad83d, 0x2172785d, 0x217a18ec, 0x2181b9ea, 0x21895b58, 0x2190fd35, 0x21989f81, 0x21a0423c, +0x21a7e566, 0x21af88ff, 0x21b72d06, 0x21bed17d, 0x21c67663, 0x21ce1bb7, 0x21d5c17a, 0x21dd67ab, +0x21e50e4b, 0x21ecb55a, 0x21f45cd7, 0x21fc04c3, 0x2203ad1d, 0x220b55e5, 0x2212ff1c, 0x221aa8c1, +0x222252d4, 0x2229fd56, 0x2231a845, 0x223953a3, 0x2240ff6e, 0x2248aba8, 0x2250584f, 0x22580565, +0x225fb2e8, 0x226760d9, 0x226f0f37, 0x2276be04, 0x227e6d3e, 0x22861ce5, 0x228dccfa, 0x22957d7d, +0x229d2e6d, 0x22a4dfcb, 0x22ac9195, 0x22b443cd, 0x22bbf673, 0x22c3a985, 0x22cb5d05, 0x22d310f2, +0x22dac54c, 0x22e27a13, 0x22ea2f47, 0x22f1e4e8, 0x22f99af5, 0x23015170, 0x23090857, 0x2310bfab, +0x2318776c, 0x23202f99, 0x2327e833, 0x232fa13a, 0x23375aad, 0x233f148c, 0x2346ced8, 0x234e8991, +0x235644b5, 0x235e0046, 0x2365bc43, 0x236d78ac, 0x23753582, 0x237cf2c3, 0x2384b071, 0x238c6e8a, +0x23942d10, 0x239bec01, 0x23a3ab5e, 0x23ab6b28, 0x23b32b5c, 0x23baebfd, 0x23c2ad09, 0x23ca6e81, +0x23d23064, 0x23d9f2b3, 0x23e1b56e, 0x23e97894, 0x23f13c25, 0x23f90022, 0x2400c48a, 0x2408895d, +0x24104e9b, 0x24181445, 0x241fda5a, 0x2427a0da, 0x242f67c5, 0x24372f1a, 0x243ef6db, 0x2446bf07, +0x244e879e, 0x2456509f, 0x245e1a0b, 0x2465e3e2, 0x246dae24, 0x247578d0, 0x247d43e7, 0x24850f68, +0x248cdb54, 0x2494a7ab, 0x249c746b, 0x24a44197, 0x24ac0f2c, 0x24b3dd2c, 0x24bbab96, 0x24c37a6a, +0x24cb49a8, 0x24d31951, 0x24dae963, 0x24e2b9e0, 0x24ea8ac6, 0x24f25c17, 0x24fa2dd1, 0x2501fff5, +0x2509d283, 0x2511a57b, 0x251978dc, 0x25214ca7, 0x252920dc, 0x2530f57b, 0x2538ca82, 0x25409ff4, +0x254875cf, 0x25504c13, 0x255822c0, 0x255ff9d7, 0x2567d157, 0x256fa941, 0x25778193, 0x257f5a4f, +0x25873374, 0x258f0d02, 0x2596e6f9, 0x259ec159, 0x25a69c22, 0x25ae7753, 0x25b652ee, 0x25be2ef1, +0x25c60b5e, 0x25cde833, 0x25d5c570, 0x25dda316, 0x25e58125, 0x25ed5f9d, 0x25f53e7c, 0x25fd1dc5, +0x2604fd76, 0x260cdd8f, 0x2614be10, 0x261c9efa, 0x2624804c, 0x262c6206, 0x26344429, 0x263c26b3, +0x264409a6, 0x264bed01, 0x2653d0c3, 0x265bb4ee, 0x26639980, 0x266b7e7b, 0x267363dd, 0x267b49a7, +0x26832fd9, 0x268b1673, 0x2692fd74, 0x269ae4dd, 0x26a2ccad, 0x26aab4e5, 0x26b29d85, 0x26ba868c, +0x26c26ffa, 0x26ca59d0, 0x26d2440d, 0x26da2eb1, 0x26e219bd, 0x26ea0530, 0x26f1f10a, 0x26f9dd4b, +0x2701c9f4, 0x2709b703, 0x2711a479, 0x27199257, 0x2721809b, 0x27296f46, 0x27315e58, 0x27394dd1, +0x27413db0, 0x27492df7, 0x27511ea4, 0x27590fb7, 0x27610132, 0x2768f312, 0x2770e55a, 0x2778d808, +0x2780cb1c, 0x2788be96, 0x2790b277, 0x2798a6bf, 0x27a09b6c, 0x27a89080, 0x27b085fa, 0x27b87bdb, +0x27c07221, 0x27c868cd, 0x27d05fe0, 0x27d85758, 0x27e04f37, 0x27e8477b, 0x27f04026, 0x27f83936, +0x280032ac, 0x28082c87, 0x281026c9, 0x28182170, 0x28201c7d, 0x282817ef, 0x283013c7, 0x28381004, +0x28400ca7, 0x284809b0, 0x2850071d, 0x285804f1, 0x28600329, 0x286801c7, 0x287000ca, 0x28780032, +0x287fffff, 0x28880032, 0x289000ca, 0x289801c6, 0x28a00328, 0x28a804ef, 0x28b0071b, 0x28b809ab, +0x28c00ca1, 0x28c80ffb, 0x28d013ba, 0x28d817de, 0x28e01c66, 0x28e82153, 0x28f026a5, 0x28f82c5b, +0x29003276, 0x290838f6, 0x29103fda, 0x29184722, 0x29204ecf, 0x292856e0, 0x29305f55, 0x2938682f, +0x2940716d, 0x29487b0f, 0x29508516, 0x29588f80, 0x29609a4f, 0x2968a582, 0x2970b118, 0x2978bd13, +0x2980c972, 0x2988d634, 0x2990e35a, 0x2998f0e5, 0x29a0fed3, 0x29a90d24, 0x29b11bda, 0x29b92af3, +0x29c13a70, 0x29c94a50, 0x29d15a94, 0x29d96b3c, 0x29e17c47, 0x29e98db5, 0x29f19f87, 0x29f9b1bc, +0x2a01c455, 0x2a09d751, 0x2a11eab0, 0x2a19fe72, 0x2a221298, 0x2a2a2721, 0x2a323c0d, 0x2a3a515c, +0x2a42670e, 0x2a4a7d23, 0x2a52939b, 0x2a5aaa75, 0x2a62c1b3, 0x2a6ad954, 0x2a72f157, 0x2a7b09be, +0x2a832287, 0x2a8b3bb2, 0x2a935541, 0x2a9b6f32, 0x2aa38986, 0x2aaba43c, 0x2ab3bf55, 0x2abbdad0, +0x2ac3f6ad, 0x2acc12ee, 0x2ad42f90, 0x2adc4c95, 0x2ae469fc, 0x2aec87c6, 0x2af4a5f1, 0x2afcc47f, +0x2b04e36f, 0x2b0d02c1, 0x2b152276, 0x2b1d428c, 0x2b256304, 0x2b2d83df, 0x2b35a51b, 0x2b3dc6b9, +0x2b45e8b9, 0x2b4e0b1b, 0x2b562ddf, 0x2b5e5104, 0x2b66748c, 0x2b6e9875, 0x2b76bcbf, 0x2b7ee16b, +0x2b870679, 0x2b8f2be9, 0x2b9751b9, 0x2b9f77ec, 0x2ba79e80, 0x2bafc575, 0x2bb7eccb, 0x2bc01483, +0x2bc83c9d, 0x2bd06517, 0x2bd88df3, 0x2be0b730, 0x2be8e0ce, 0x2bf10acd, 0x2bf9352e, 0x2c015fef, +0x2c098b11, 0x2c11b695, 0x2c19e279, 0x2c220ebf, 0x2c2a3b65, 0x2c32686c, 0x2c3a95d4, 0x2c42c39c, +0x2c4af1c6, 0x2c532050, 0x2c5b4f3a, 0x2c637e86, 0x2c6bae32, 0x2c73de3e, 0x2c7c0eab, 0x2c843f79, +0x2c8c70a7, 0x2c94a236, 0x2c9cd424, 0x2ca50674, 0x2cad3923, 0x2cb56c33, 0x2cbd9fa3, 0x2cc5d374, +0x2cce07a4, 0x2cd63c35, 0x2cde7126, 0x2ce6a677, 0x2ceedc28, 0x2cf71238, 0x2cff48a9, 0x2d077f7a, +0x2d0fb6ab, 0x2d17ee3c, 0x2d20262c, 0x2d285e7d, 0x2d30972d, 0x2d38d03d, 0x2d4109ac, 0x2d49437c, +0x2d517daa, 0x2d59b839, 0x2d61f327, 0x2d6a2e75, 0x2d726a22, 0x2d7aa62e, 0x2d82e29b, 0x2d8b1f66, +0x2d935c91, 0x2d9b9a1b, 0x2da3d804, 0x2dac164d, 0x2db454f5, 0x2dbc93fc, 0x2dc4d363, 0x2dcd1328, +0x2dd5534d, 0x2ddd93d0, 0x2de5d4b3, 0x2dee15f5, 0x2df65795, 0x2dfe9995, 0x2e06dbf4, 0x2e0f1eb1, +0x2e1761cd, 0x2e1fa548, 0x2e27e922, 0x2e302d5a, 0x2e3871f2, 0x2e40b6e8, 0x2e48fc3c, 0x2e5141ef, +0x2e598801, 0x2e61ce71, 0x2e6a1540, 0x2e725c6d, 0x2e7aa3f9, 0x2e82ebe3, 0x2e8b342b, 0x2e937cd2, +0x2e9bc5d7, 0x2ea40f3b, 0x2eac58fc, 0x2eb4a31c, 0x2ebced9a, 0x2ec53876, 0x2ecd83b0, 0x2ed5cf49, +0x2ede1b3f, 0x2ee66794, 0x2eeeb446, 0x2ef70156, 0x2eff4ec5, 0x2f079c91, 0x2f0feabb, 0x2f183942, +0x2f208828, 0x2f28d76b, 0x2f31270c, 0x2f39770b, 0x2f41c768, 0x2f4a1822, 0x2f526939, 0x2f5abaaf, +0x2f630c81, 0x2f6b5eb2, 0x2f73b13f, 0x2f7c042a, 0x2f845773, 0x2f8cab19, 0x2f94ff1c, 0x2f9d537d, +0x2fa5a83a, 0x2fadfd56, 0x2fb652ce, 0x2fbea8a3, 0x2fc6fed6, 0x2fcf5566, 0x2fd7ac52, 0x2fe0039c, +0x2fe85b43, 0x2ff0b347, 0x2ff90ba8, 0x30016466, 0x3009bd80, 0x301216f8, 0x301a70cc, 0x3022cafd, +0x302b258b, 0x30338076, 0x303bdbbd, 0x30443761, 0x304c9362, 0x3054efbf, 0x305d4c79, 0x3065a98f, +0x306e0702, 0x307664d2, 0x307ec2fe, 0x30872186, 0x308f806b, 0x3097dfac, 0x30a03f49, 0x30a89f43, +0x30b0ff99, 0x30b9604b, 0x30c1c159, 0x30ca22c4, 0x30d2848a, 0x30dae6ad, 0x30e3492c, 0x30ebac07, +0x30f40f3e, 0x30fc72d1, 0x3104d6c0, 0x310d3b0b, 0x31159fb1, 0x311e04b4, 0x31266a12, 0x312ecfcd, +0x313735e3, 0x313f9c55, 0x31480322, 0x31506a4b, 0x3158d1d0, 0x316139b0, 0x3169a1ed, 0x31720a84, +0x317a7377, 0x3182dcc6, 0x318b4670, 0x3193b076, 0x319c1ad6, 0x31a48593, 0x31acf0aa, 0x31b55c1d, +0x31bdc7ec, 0x31c63415, 0x31cea09a, 0x31d70d7a, 0x31df7ab5, 0x31e7e84b, 0x31f0563d, 0x31f8c489, +0x32013331, 0x3209a233, 0x32121191, 0x321a8149, 0x3222f15d, 0x322b61cb, 0x3233d294, 0x323c43b8, +0x3244b537, 0x324d2711, 0x32559945, 0x325e0bd4, 0x32667ebe, 0x326ef202, 0x327765a1, 0x327fd99b, +0x32884def, 0x3290c29e, 0x329937a7, 0x32a1ad0b, 0x32aa22c9, 0x32b298e2, 0x32bb0f55, 0x32c38622, +0x32cbfd4a, 0x32d474cc, 0x32dceca8, 0x32e564df, 0x32eddd70, 0x32f6565b, 0x32fecfa0, 0x3307493f, +0x330fc338, 0x33183d8c, 0x3320b839, 0x33293341, 0x3331aea2, 0x333a2a5e, 0x3342a673, 0x334b22e2, +0x33539fab, 0x335c1cce, 0x33649a4b, 0x336d1821, 0x33759652, 0x337e14dc, 0x338693bf, 0x338f12fd, +0x33979294, 0x33a01284, 0x33a892cf, 0x33b11372, 0x33b9946f, 0x33c215c6, 0x33ca9776, 0x33d31980, +0x33db9be3, 0x33e41ea0, 0x33eca1b5, 0x33f52524, 0x33fda8ed, 0x34062d0e, 0x340eb189, 0x3417365d, +0x341fbb8b, 0x34284111, 0x3430c6f1, 0x34394d29, 0x3441d3bb, 0x344a5aa6, 0x3452e1e9, 0x345b6986, +0x3463f17c, 0x346c79ca, 0x34750272, 0x347d8b72, 0x348614cb, 0x348e9e7d, 0x34972888, 0x349fb2eb, +0x34a83da8, 0x34b0c8bd, 0x34b9542a, 0x34c1dff0, 0x34ca6c0f, 0x34d2f887, 0x34db8557, 0x34e4127f, +0x34eca000, 0x34f52dda, 0x34fdbc0c, 0x35064a96, 0x350ed979, 0x351768b4, 0x351ff847, 0x35288833, +0x35311877, 0x3539a913, 0x35423a08, 0x354acb54, 0x35535cf9, 0x355beef6, 0x3564814b, 0x356d13f8, +0x3575a6fe, 0x357e3a5b, 0x3586ce10, 0x358f621d, 0x3597f682, 0x35a08b40, 0x35a92055, 0x35b1b5c1, +0x35ba4b86, 0x35c2e1a3, 0x35cb7817, 0x35d40ee3, 0x35dca607, 0x35e53d82, 0x35edd555, 0x35f66d80, +0x35ff0602, 0x36079edc, 0x3610380e, 0x3618d197, 0x36216b77, 0x362a05af, 0x3632a03f, 0x363b3b26, +0x3643d664, 0x364c71fa, 0x36550de7, 0x365daa2b, 0x366646c7, 0x366ee3ba, 0x36778104, 0x36801ea5, +0x3688bc9e, 0x36915aee, 0x3699f994, 0x36a29892, 0x36ab37e7, 0x36b3d793, 0x36bc7796, 0x36c517f1, +0x36cdb8a2, 0x36d659aa, 0x36defb08, 0x36e79cbe, 0x36f03ecb, 0x36f8e12e, 0x370183e9, 0x370a26fa, +0x3712ca62, 0x371b6e20, 0x37241235, 0x372cb6a1, 0x37355b64, 0x373e007d, 0x3746a5ed, 0x374f4bb3, +0x3757f1d0, 0x37609844, 0x37693f0e, 0x3771e62e, 0x377a8da5, 0x37833572, 0x378bdd96, 0x37948610, +0x379d2ee0, 0x37a5d807, 0x37ae8183, 0x37b72b57, 0x37bfd580, 0x37c87fff, 0x37d12ad5, 0x37d9d601, +0x37e28183, 0x37eb2d5b, 0x37f3d989, 0x37fc860e, 0x380532e8, 0x380de018, 0x38168d9e, 0x381f3b7b, +0x3827e9ad, 0x38309835, 0x38394712, 0x3841f646, 0x384aa5d0, 0x385355af, 0x385c05e4, 0x3864b66f, +0x386d674f, 0x38761885, 0x387eca11, 0x38877bf2, 0x38902e29, 0x3898e0b6, 0x38a19398, 0x38aa46d0, +0x38b2fa5d, 0x38bbae40, 0x38c46278, 0x38cd1705, 0x38d5cbe8, 0x38de8120, 0x38e736ae, 0x38efec91, +0x38f8a2c9, 0x39015957, 0x390a103a, 0x3912c772, 0x391b7eff, 0x392436e1, 0x392cef19, 0x3935a7a5, +0x393e6087, 0x394719be, 0x394fd34a, 0x39588d2b, 0x39614760, 0x396a01eb, 0x3972bccb, 0x397b7800, +0x39843389, 0x398cef68, 0x3995ab9b, 0x399e6823, 0x39a72500, 0x39afe232, 0x39b89fb8, 0x39c15d93, +0x39ca1bc3, 0x39d2da47, 0x39db9921, 0x39e4584e, 0x39ed17d1, 0x39f5d7a8, 0x39fe97d3, 0x3a075853, +0x3a101927, 0x3a18da50, 0x3a219bce, 0x3a2a5d9f, 0x3a331fc5, 0x3a3be240, 0x3a44a50f, 0x3a4d6832, +0x3a562ba9, 0x3a5eef75, 0x3a67b395, 0x3a707809, 0x3a793cd2, 0x3a8201ee, 0x3a8ac75f, 0x3a938d24, +0x3a9c533d, 0x3aa519aa, 0x3aade06b, 0x3ab6a780, 0x3abf6ee9, 0x3ac836a6, 0x3ad0feb7, 0x3ad9c71c, +0x3ae28fd5, 0x3aeb58e1, 0x3af42242, 0x3afcebf6, 0x3b05b5fe, 0x3b0e805a, 0x3b174b0a, 0x3b20160d, +0x3b28e164, 0x3b31ad0f, 0x3b3a790e, 0x3b434560, 0x3b4c1205, 0x3b54deff, 0x3b5dac4b, 0x3b6679ec, +0x3b6f47e0, 0x3b781627, 0x3b80e4c2, 0x3b89b3b0, 0x3b9282f2, 0x3b9b5287, 0x3ba4226f, 0x3bacf2ab, +0x3bb5c33a, 0x3bbe941c, 0x3bc76552, 0x3bd036db, 0x3bd908b7, 0x3be1dae6, 0x3beaad69, 0x3bf3803e, +0x3bfc5367, 0x3c0526e3, 0x3c0dfab2, 0x3c16ced4, 0x3c1fa349, 0x3c287811, 0x3c314d2c, 0x3c3a229a, +0x3c42f85b, 0x3c4bce6f, 0x3c54a4d5, 0x3c5d7b8f, 0x3c66529b, 0x3c6f29fa, 0x3c7801ac, 0x3c80d9b1, +0x3c89b209, 0x3c928ab3, 0x3c9b63b0, 0x3ca43cff, 0x3cad16a2, 0x3cb5f097, 0x3cbecade, 0x3cc7a578, +0x3cd08065, 0x3cd95ba4, 0x3ce23736, 0x3ceb131a, 0x3cf3ef50, 0x3cfccbd9, 0x3d05a8b5, 0x3d0e85e3, +0x3d176363, 0x3d204136, 0x3d291f5b, 0x3d31fdd2, 0x3d3adc9b, 0x3d43bbb7, 0x3d4c9b25, 0x3d557ae5, +0x3d5e5af7, 0x3d673b5c, 0x3d701c13, 0x3d78fd1b, 0x3d81de76, 0x3d8ac023, 0x3d93a222, 0x3d9c8473, +0x3da56716, 0x3dae4a0b, 0x3db72d52, 0x3dc010eb, 0x3dc8f4d6, 0x3dd1d912, 0x3ddabda1, 0x3de3a281, +0x3dec87b3, 0x3df56d37, 0x3dfe530d, 0x3e073934, 0x3e101fad, 0x3e190678, 0x3e21ed95, 0x3e2ad503, +0x3e33bcc3, 0x3e3ca4d4, 0x3e458d37, 0x3e4e75ec, 0x3e575ef2, 0x3e60484a, 0x3e6931f3, 0x3e721bed, +0x3e7b0639, 0x3e83f0d7, 0x3e8cdbc6, 0x3e95c706, 0x3e9eb298, 0x3ea79e7a, 0x3eb08aaf, 0x3eb97734, +0x3ec2640b, 0x3ecb5133, 0x3ed43eac, 0x3edd2c77, 0x3ee61a93, 0x3eef08ff, 0x3ef7f7bd, 0x3f00e6cc, +0x3f09d62c, 0x3f12c5de, 0x3f1bb5e0, 0x3f24a633, 0x3f2d96d7, 0x3f3687cd, 0x3f3f7913, 0x3f486aaa, +0x3f515c92, 0x3f5a4ecb, 0x3f634155, 0x3f6c342f, 0x3f75275b, 0x3f7e1ad7, 0x3f870ea4, 0x3f9002c2, +0x3f98f730, 0x3fa1ebef, 0x3faae0ff, 0x3fb3d660, 0x3fbccc11, 0x3fc5c213, 0x3fceb865, 0x3fd7af08, +0x3fe0a5fc, 0x3fe99d40, 0x3ff294d4, 0x3ffb8cb9, 0x400484ef, 0x400d7d75, 0x4016764b, 0x401f6f72, +0x402868e9, 0x403162b1, 0x403a5cc8, 0x40435730, 0x404c51e9, 0x40554cf2, 0x405e484b, 0x406743f4, +0x40703fed, 0x40793c37, 0x408238d0, 0x408b35ba, 0x409432f4, 0x409d307e, 0x40a62e58, 0x40af2c82, +0x40b82afd, 0x40c129c7, 0x40ca28e1, 0x40d3284b, 0x40dc2805, 0x40e5280f, 0x40ee2869, 0x40f72913, +0x41002a0c, 0x41092b56, 0x41122cef, 0x411b2ed8, 0x41243111, 0x412d3399, 0x41363672, 0x413f399a, +0x41483d11, 0x415140d9, 0x415a44f0, 0x41634956, 0x416c4e0c, 0x41755312, 0x417e5867, 0x41875e0c, +0x41906401, 0x41996a44, 0x41a270d8, 0x41ab77ba, 0x41b47eed, 0x41bd866e, 0x41c68e3f, 0x41cf965f, +0x41d89ecf, 0x41e1a78e, 0x41eab09c, 0x41f3b9fa, 0x41fcc3a6, 0x4205cda2, 0x420ed7ee, 0x4217e288, +0x4220ed72, 0x4229f8aa, 0x42330432, 0x423c1009, 0x42451c2f, 0x424e28a4, 0x42573569, 0x4260427c, +0x42694fde, 0x42725d8f, 0x427b6b8f, 0x428479de, 0x428d887c, 0x42969769, 0x429fa6a5, 0x42a8b62f, +0x42b1c609, 0x42bad631, 0x42c3e6a8, 0x42ccf76e, 0x42d60882, 0x42df19e5, 0x42e82b97, 0x42f13d98, +0x42fa4fe7, 0x43036285, 0x430c7572, 0x431588ad, 0x431e9c37, 0x4327b00f, 0x4330c436, 0x4339d8ab, +0x4342ed6f, 0x434c0282, 0x435517e3, 0x435e2d92, 0x4367438f, 0x437059dc, 0x43797076, 0x4382875f, +0x438b9e96, 0x4394b61b, 0x439dcdef, 0x43a6e611, 0x43affe81, 0x43b91740, 0x43c2304d, 0x43cb49a8, +0x43d46351, 0x43dd7d48, 0x43e6978d, 0x43efb221, 0x43f8cd02, 0x4401e832, 0x440b03af, 0x44141f7b, +0x441d3b95, 0x442657fc, 0x442f74b2, 0x443891b6, 0x4441af07, 0x444acca7, 0x4453ea94, 0x445d08cf, +0x44662758, 0x446f462f, 0x44786553, 0x448184c6, 0x448aa486, 0x4493c494, 0x449ce4f0, 0x44a60599, +0x44af2690, 0x44b847d5, 0x44c16967, 0x44ca8b47, 0x44d3ad74, 0x44dccfef, 0x44e5f2b8, 0x44ef15ce, +0x44f83932, 0x45015ce3, 0x450a80e2, 0x4513a52e, 0x451cc9c8, 0x4525eeaf, 0x452f13e3, 0x45383965, +0x45415f34, 0x454a8551, 0x4553abbb, 0x455cd272, 0x4565f976, 0x456f20c8, 0x45784867, 0x45817053, +0x458a988c, 0x4593c113, 0x459ce9e7, 0x45a61307, 0x45af3c75, 0x45b86630, 0x45c19039, 0x45caba8e, +0x45d3e530, 0x45dd101f, 0x45e63b5c, 0x45ef66e5, 0x45f892bb, 0x4601bede, 0x460aeb4e, 0x4614180b, +0x461d4515, 0x4626726c, 0x462fa00f, 0x4638ce00, 0x4641fc3d, 0x464b2ac7, 0x4654599e, 0x465d88c1, +0x4666b832, 0x466fe7ef, 0x467917f8, 0x4682484e, 0x468b78f1, 0x4694a9e1, 0x469ddb1d, 0x46a70ca6, +0x46b03e7b, 0x46b9709d, 0x46c2a30c, 0x46cbd5c7, 0x46d508ce, 0x46de3c22, 0x46e76fc2, 0x46f0a3af, +0x46f9d7e9, 0x47030c6e, 0x470c4140, 0x4715765f, 0x471eabc9, 0x4727e180, 0x47311784, 0x473a4dd3, +0x4743846f, 0x474cbb57, 0x4755f28c, 0x475f2a0c, 0x476861d9, 0x477199f2, 0x477ad257, 0x47840b08, +0x478d4405, 0x47967d4f, 0x479fb6e4, 0x47a8f0c5, 0x47b22af3, 0x47bb656c, 0x47c4a032, 0x47cddb43, +0x47d716a1, 0x47e0524a, 0x47e98e40, 0x47f2ca81, 0x47fc070e, 0x480543e7, 0x480e810c, 0x4817be7c, +0x4820fc39, 0x482a3a41, 0x48337895, 0x483cb735, 0x4845f620, 0x484f3557, 0x485874da, 0x4861b4a8, +0x486af4c3, 0x48743528, 0x487d75da, 0x4886b6d7, 0x488ff81f, 0x489939b3, 0x48a27b93, 0x48abbdbe, +0x48b50035, 0x48be42f7, 0x48c78605, 0x48d0c95e, 0x48da0d02, 0x48e350f2, 0x48ec952e, 0x48f5d9b4, +0x48ff1e86, 0x490863a4, 0x4911a90c, 0x491aeec0, 0x492434bf, 0x492d7b0a, 0x4936c1a0, 0x49400881, +0x49494fad, 0x49529724, 0x495bdee7, 0x496526f4, 0x496e6f4d, 0x4977b7f1, 0x498100e0, 0x498a4a1a, +0x4993939f, 0x499cdd6f, 0x49a6278a, 0x49af71f0, 0x49b8bca2, 0x49c2079e, 0x49cb52e5, 0x49d49e77, +0x49ddea53, 0x49e7367b, 0x49f082ee, 0x49f9cfab, 0x4a031cb4, 0x4a0c6a07, 0x4a15b7a5, 0x4a1f058d, +0x4a2853c1, 0x4a31a23f, 0x4a3af108, 0x4a44401b, 0x4a4d8f7a, 0x4a56df23, 0x4a602f16, 0x4a697f55, +0x4a72cfdd, 0x4a7c20b1, 0x4a8571cf, 0x4a8ec337, 0x4a9814eb, 0x4aa166e8, 0x4aaab930, 0x4ab40bc3, +0x4abd5ea0, 0x4ac6b1c8, 0x4ad0053a, 0x4ad958f6, 0x4ae2acfd, 0x4aec014e, 0x4af555e9, 0x4afeaacf, +0x4b07ffff, 0x4b11557a, 0x4b1aab3f, 0x4b24014e, 0x4b2d57a7, 0x4b36ae4b, 0x4b400538, 0x4b495c70, +0x4b52b3f2, 0x4b5c0bbf, 0x4b6563d5, 0x4b6ebc36, 0x4b7814e0, 0x4b816dd5, 0x4b8ac714, 0x4b94209d, +0x4b9d7a6f, 0x4ba6d48c, 0x4bb02ef3, 0x4bb989a4, 0x4bc2e49f, 0x4bcc3fe4, 0x4bd59b72, 0x4bdef74b, +0x4be8536e, 0x4bf1afda, 0x4bfb0c90, 0x4c046990, 0x4c0dc6da, 0x4c17246e, 0x4c20824b, 0x4c29e073, +0x4c333ee4, 0x4c3c9d9e, 0x4c45fca3, 0x4c4f5bf1, 0x4c58bb89, 0x4c621b6a, 0x4c6b7b95, 0x4c74dc0a, +0x4c7e3cc9, 0x4c879dd0, 0x4c90ff22, 0x4c9a60bd, 0x4ca3c2a2, 0x4cad24d0, 0x4cb68747, 0x4cbfea09, +0x4cc94d13, 0x4cd2b067, 0x4cdc1405, 0x4ce577ec, 0x4ceedc1c, 0x4cf84096, 0x4d01a559, 0x4d0b0a65, +0x4d146fbb, 0x4d1dd55a, 0x4d273b42, 0x4d30a174, 0x4d3a07ee, 0x4d436eb2, 0x4d4cd5c0, 0x4d563d16, +0x4d5fa4b6, 0x4d690c9f, 0x4d7274d1, 0x4d7bdd4c, 0x4d854610, 0x4d8eaf1e, 0x4d981874, 0x4da18214, +0x4daaebfc, 0x4db4562e, 0x4dbdc0a8, 0x4dc72b6c, 0x4dd09679, 0x4dda01ce, 0x4de36d6d, 0x4decd954, +0x4df64584, 0x4dffb1fe, 0x4e091ec0, 0x4e128bcb, 0x4e1bf91f, 0x4e2566bb, 0x4e2ed4a1, 0x4e3842cf, +0x4e41b146, 0x4e4b2006, 0x4e548f0e, 0x4e5dfe5f, 0x4e676df9, 0x4e70dddc, 0x4e7a4e07, 0x4e83be7b, +0x4e8d2f38, 0x4e96a03d, 0x4ea0118b, 0x4ea98321, 0x4eb2f500, 0x4ebc6728, 0x4ec5d998, 0x4ecf4c50, +0x4ed8bf51, 0x4ee2329b, 0x4eeba62d, 0x4ef51a07, 0x4efe8e2a, 0x4f080296, 0x4f117749, 0x4f1aec45, +0x4f24618a, 0x4f2dd717, 0x4f374cec, 0x4f40c309, 0x4f4a396f, 0x4f53b01d, 0x4f5d2713, 0x4f669e52, +0x4f7015d9, 0x4f798da8, 0x4f8305bf, 0x4f8c7e1e, 0x4f95f6c6, 0x4f9f6fb5, 0x4fa8e8ed, 0x4fb2626d, +0x4fbbdc35, 0x4fc55645, 0x4fced09d, 0x4fd84b3e, 0x4fe1c626, 0x4feb4156, 0x4ff4bcce, 0x4ffe388f, +0x5007b497, 0x501130e7, 0x501aad7f, 0x50242a5f, 0x502da787, 0x503724f7, 0x5040a2ae, 0x504a20ae, +0x50539ef5, 0x505d1d84, 0x50669c5b, 0x50701b7a, 0x50799ae0, 0x50831a8e, 0x508c9a84, 0x50961ac2, +0x509f9b47, 0x50a91c14, 0x50b29d29, 0x50bc1e85, 0x50c5a029, 0x50cf2215, 0x50d8a448, 0x50e226c2, +0x50eba985, 0x50f52c8f, 0x50feafe0, 0x51083379, 0x5111b759, 0x511b3b81, 0x5124bff1, 0x512e44a7, +0x5137c9a6, 0x51414eeb, 0x514ad478, 0x51545a4d, 0x515de069, 0x516766cc, 0x5170ed76, 0x517a7468, +0x5183fba1, 0x518d8322, 0x51970ae9, 0x51a092f8, 0x51aa1b4e, 0x51b3a3ec, 0x51bd2cd0, 0x51c6b5fc, +0x51d03f6f, 0x51d9c929, 0x51e3532b, 0x51ecdd73, 0x51f66802, 0x51fff2d9, 0x52097df7, 0x5213095b, +0x521c9507, 0x522620fa, 0x522fad34, 0x523939b5, 0x5242c67c, 0x524c538b, 0x5255e0e1, 0x525f6e7e, +0x5268fc61, 0x52728a8c, 0x527c18fd, 0x5285a7b5, 0x528f36b4, 0x5298c5fa, 0x52a25587, 0x52abe55a, +0x52b57575, 0x52bf05d6, 0x52c8967d, 0x52d2276c, 0x52dbb8a1, 0x52e54a1d, 0x52eedbe0, 0x52f86de9, +0x53020039, 0x530b92d0, 0x531525ad, 0x531eb8d1, 0x53284c3c, 0x5331dfed, 0x533b73e4, 0x53450823, +0x534e9ca7, 0x53583173, 0x5361c684, 0x536b5bdc, 0x5374f17b, 0x537e8760, 0x53881d8c, 0x5391b3fe, +0x539b4ab6, 0x53a4e1b5, 0x53ae78fa, 0x53b81086, 0x53c1a858, 0x53cb4070, 0x53d4d8ce, 0x53de7173, +0x53e80a5e, 0x53f1a390, 0x53fb3d07, 0x5404d6c5, 0x540e70c9, 0x54180b13, 0x5421a5a4, 0x542b407a, +0x5434db97, 0x543e76fa, 0x544812a3, 0x5451ae92, 0x545b4ac8, 0x5464e743, 0x546e8404, 0x5478210c, +0x5481be59, 0x548b5bed, 0x5494f9c6, 0x549e97e5, 0x54a8364b, 0x54b1d4f6, 0x54bb73e8, 0x54c5131f, +0x54ceb29c, 0x54d8525f, 0x54e1f268, 0x54eb92b6, 0x54f5334b, 0x54fed425, 0x55087546, 0x551216ac, +0x551bb858, 0x55255a49, 0x552efc80, 0x55389efe, 0x554241c0, 0x554be4c9, 0x55558817, 0x555f2bab, +0x5568cf84, 0x557273a3, 0x557c1808, 0x5585bcb3, 0x558f61a3, 0x559906d8, 0x55a2ac53, 0x55ac5214, +0x55b5f81a, 0x55bf9e66, 0x55c944f7, 0x55d2ebce, 0x55dc92ea, 0x55e63a4c, 0x55efe1f3, 0x55f989e0, +0x56033212, 0x560cda89, 0x56168346, 0x56202c48, 0x5629d58f, 0x56337f1c, 0x563d28ee, 0x5646d306, +0x56507d62, 0x565a2804, 0x5663d2ec, 0x566d7e18, 0x5677298a, 0x5680d541, 0x568a813d, 0x56942d7e, +0x569dda05, 0x56a786d1, 0x56b133e1, 0x56bae137, 0x56c48ed2, 0x56ce3cb3, 0x56d7ead8, 0x56e19942, +0x56eb47f1, 0x56f4f6e6, 0x56fea61f, 0x5708559e, 0x57120561, 0x571bb569, 0x572565b7, 0x572f1649, +0x5738c720, 0x5742783c, 0x574c299e, 0x5755db43, 0x575f8d2e, 0x57693f5e, 0x5772f1d2, 0x577ca48c, +0x5786578a, 0x57900acd, 0x5799be54, 0x57a37221, 0x57ad2632, 0x57b6da88, 0x57c08f23, 0x57ca4402, +0x57d3f926, 0x57ddae8f, 0x57e7643c, 0x57f11a2f, 0x57fad065, 0x580486e1, 0x580e3da1, 0x5817f4a5, +0x5821abee, 0x582b637c, 0x58351b4e, 0x583ed365, 0x58488bc0, 0x58524460, 0x585bfd44, 0x5865b66d, +0x586f6fda, 0x5879298b, 0x5882e381, 0x588c9dbc, 0x5896583b, 0x58a012fe, 0x58a9ce05, 0x58b38951, +0x58bd44e2, 0x58c700b6, 0x58d0bccf, 0x58da792c, 0x58e435ce, 0x58edf2b4, 0x58f7afde, 0x59016d4c, +0x590b2afe, 0x5914e8f5, 0x591ea730, 0x592865af, 0x59322472, 0x593be379, 0x5945a2c5, 0x594f6255, +0x59592228, 0x5962e240, 0x596ca29c, 0x5976633c, 0x59802420, 0x5989e548, 0x5993a6b4, 0x599d6864, +0x59a72a58, 0x59b0ec90, 0x59baaf0c, 0x59c471cc, 0x59ce34d0, 0x59d7f818, 0x59e1bba3, 0x59eb7f73, +0x59f54386, 0x59ff07dd, 0x5a08cc79, 0x5a129158, 0x5a1c567a, 0x5a261be1, 0x5a2fe18b, 0x5a39a779, +0x5a436dab, 0x5a4d3421, 0x5a56fada, 0x5a60c1d8, 0x5a6a8918, 0x5a74509d, 0x5a7e1865, 0x5a87e071, +0x5a91a8c0, 0x5a9b7153, 0x5aa53a2a, 0x5aaf0344, 0x5ab8cca2, 0x5ac29644, 0x5acc6029, 0x5ad62a51, +0x5adff4bd, 0x5ae9bf6d, 0x5af38a60, 0x5afd5597, 0x5b072111, 0x5b10ecce, 0x5b1ab8cf, 0x5b248514, +0x5b2e519c, 0x5b381e67, 0x5b41eb76, 0x5b4bb8c8, 0x5b55865d, 0x5b5f5436, 0x5b692252, 0x5b72f0b1, +0x5b7cbf54, 0x5b868e3a, 0x5b905d63, 0x5b9a2cd0, 0x5ba3fc7f, 0x5badcc72, 0x5bb79ca9, 0x5bc16d22, +0x5bcb3ddf, 0x5bd50ede, 0x5bdee021, 0x5be8b1a7, 0x5bf28371, 0x5bfc557d, 0x5c0627cc, 0x5c0ffa5f, +0x5c19cd35, 0x5c23a04d, 0x5c2d73a9, 0x5c374748, 0x5c411b2a, 0x5c4aef4e, 0x5c54c3b6, 0x5c5e9861, +0x5c686d4f, 0x5c724280, 0x5c7c17f3, 0x5c85edaa, 0x5c8fc3a3, 0x5c9999e0, 0x5ca3705f, 0x5cad4721, +0x5cb71e26, 0x5cc0f56e, 0x5ccaccf9, 0x5cd4a4c6, 0x5cde7cd7, 0x5ce8552a, 0x5cf22dbf, 0x5cfc0698, +0x5d05dfb3, 0x5d0fb912, 0x5d1992b2, 0x5d236c96, 0x5d2d46bc, 0x5d372125, 0x5d40fbd1, 0x5d4ad6bf, +0x5d54b1f0, 0x5d5e8d63, 0x5d686919, 0x5d724512, 0x5d7c214d, 0x5d85fdcb, 0x5d8fda8b, 0x5d99b78e, +0x5da394d4, 0x5dad725c, 0x5db75026, 0x5dc12e33, 0x5dcb0c82, 0x5dd4eb14, 0x5ddec9e9, 0x5de8a8ff, +0x5df28858, 0x5dfc67f4, 0x5e0647d2, 0x5e1027f2, 0x5e1a0855, 0x5e23e8fa, 0x5e2dc9e1, 0x5e37ab0b, +0x5e418c77, 0x5e4b6e25, 0x5e555016, 0x5e5f3249, 0x5e6914be, 0x5e72f775, 0x5e7cda6f, 0x5e86bdab, +0x5e90a129, 0x5e9a84e9, 0x5ea468eb, 0x5eae4d30, 0x5eb831b6, 0x5ec2167f, 0x5ecbfb8a, 0x5ed5e0d7, +0x5edfc666, 0x5ee9ac37, 0x5ef3924a, 0x5efd78a0, 0x5f075f37, 0x5f114610, 0x5f1b2d2c, 0x5f251489, +0x5f2efc28, 0x5f38e40a, 0x5f42cc2d, 0x5f4cb492, 0x5f569d39, 0x5f608622, 0x5f6a6f4d, 0x5f7458ba, +0x5f7e4269, 0x5f882c5a, 0x5f92168c, 0x5f9c0100, 0x5fa5ebb6, 0x5fafd6ae, 0x5fb9c1e8, 0x5fc3ad64, +0x5fcd9921, 0x5fd78520, 0x5fe17161, 0x5feb5de3, 0x5ff54aa7, 0x5fff37ad, 0x600924f5, 0x6013127e, +0x601d0049, 0x6026ee56, 0x6030dca4, 0x603acb34, 0x6044ba05, 0x604ea918, 0x6058986d, 0x60628803, +0x606c77db, 0x607667f4, 0x6080584f, 0x608a48ec, 0x609439ca, 0x609e2ae9, 0x60a81c4a, 0x60b20dec, +0x60bbffd0, 0x60c5f1f5, 0x60cfe45c, 0x60d9d704, 0x60e3c9ed, 0x60edbd18, 0x60f7b084, 0x6101a432, +0x610b9821, 0x61158c51, 0x611f80c3, 0x61297576, 0x61336a6a, 0x613d5f9f, 0x61475516, 0x61514ace, +0x615b40c7, 0x61653702, 0x616f2d7e, 0x6179243a, 0x61831b38, 0x618d1278, 0x619709f8, 0x61a101ba, +0x61aaf9bd, 0x61b4f200, 0x61beea85, 0x61c8e34b, 0x61d2dc53, 0x61dcd59b, 0x61e6cf24, 0x61f0c8ee, +0x61fac2fa, 0x6204bd46, 0x620eb7d4, 0x6218b2a2, 0x6222adb1, 0x622ca902, 0x6236a493, 0x6240a065, +0x624a9c78, 0x625498cd, 0x625e9562, 0x62689238, 0x62728f4e, 0x627c8ca6, 0x62868a3e, 0x62908818, +0x629a8632, 0x62a4848d, 0x62ae8329, 0x62b88205, 0x62c28123, 0x62cc8081, 0x62d68020, 0x62e07fff, +0x62ea8020, 0x62f48081, 0x62fe8123, 0x63088205, 0x63128328, 0x631c848c, 0x63268631, 0x63308816, +0x633a8a3b, 0x63448ca2, 0x634e8f49, 0x63589230, 0x63629558, 0x636c98c1, 0x63769c6a, 0x6380a054, +0x638aa47e, 0x6394a8e9, 0x639ead94, 0x63a8b280, 0x63b2b7ac, 0x63bcbd19, 0x63c6c2c6, 0x63d0c8b3, +0x63dacee1, 0x63e4d550, 0x63eedbff, 0x63f8e2ee, 0x6402ea1d, 0x640cf18d, 0x6416f93e, 0x6421012e, +0x642b095f, 0x643511d0, 0x643f1a82, 0x64492374, 0x64532ca6, 0x645d3618, 0x64673fcb, 0x647149bd, +0x647b53f0, 0x64855e64, 0x648f6917, 0x6499740b, 0x64a37f3e, 0x64ad8ab2, 0x64b79666, 0x64c1a25b, +0x64cbae8f, 0x64d5bb03, 0x64dfc7b8, 0x64e9d4ad, 0x64f3e1e1, 0x64fdef56, 0x6507fd0b, 0x65120b00, +0x651c1934, 0x652627a9, 0x6530365e, 0x653a4553, 0x65445488, 0x654e63fd, 0x655873b1, 0x656283a6, +0x656c93db, 0x6576a44f, 0x6580b503, 0x658ac5f8, 0x6594d72c, 0x659ee8a0, 0x65a8fa54, 0x65b30c47, +0x65bd1e7b, 0x65c730ee, 0x65d143a1, 0x65db5694, 0x65e569c7, 0x65ef7d39, 0x65f990eb, 0x6603a4dd, +0x660db90f, 0x6617cd80, 0x6621e231, 0x662bf722, 0x66360c52, 0x664021c2, 0x664a3772, 0x66544d62, +0x665e6390, 0x666879ff, 0x667290ad, 0x667ca79b, 0x6686bec8, 0x6690d635, 0x669aede2, 0x66a505ce, +0x66af1df9, 0x66b93664, 0x66c34f0f, 0x66cd67f9, 0x66d78123, 0x66e19a8c, 0x66ebb434, 0x66f5ce1c, +0x66ffe843, 0x670a02aa, 0x67141d50, 0x671e3836, 0x6728535b, 0x67326ebf, 0x673c8a63, 0x6746a646, +0x6750c268, 0x675adeca, 0x6764fb6b, 0x676f184b, 0x6779356a, 0x678352c9, 0x678d7067, 0x67978e45, +0x67a1ac61, 0x67abcabd, 0x67b5e958, 0x67c00832, 0x67ca274c, 0x67d446a4, 0x67de663c, 0x67e88613, +0x67f2a629, 0x67fcc67e, 0x6806e712, 0x681107e6, 0x681b28f8, 0x68254a4a, 0x682f6bda, 0x68398daa, +0x6843afb9, 0x684dd206, 0x6857f493, 0x6862175f, 0x686c3a6a, 0x68765db3, 0x6880813c, 0x688aa504, +0x6894c90a, 0x689eed50, 0x68a911d5, 0x68b33698, 0x68bd5b9a, 0x68c780dc, 0x68d1a65c, 0x68dbcc1b, +0x68e5f218, 0x68f01855, 0x68fa3ed0, 0x6904658b, 0x690e8c84, 0x6918b3bc, 0x6922db32, 0x692d02e8, +0x69372adc, 0x6941530f, 0x694b7b81, 0x6955a431, 0x695fcd20, 0x6969f64e, 0x69741fbb, 0x697e4966, +0x69887350, 0x69929d78, 0x699cc7df, 0x69a6f285, 0x69b11d69, 0x69bb488c, 0x69c573ee, 0x69cf9f8e, +0x69d9cb6d, 0x69e3f78a, 0x69ee23e6, 0x69f85080, 0x6a027d59, 0x6a0caa71, 0x6a16d7c7, 0x6a21055b, +0x6a2b332e, 0x6a35613f, 0x6a3f8f8f, 0x6a49be1d, 0x6a53ecea, 0x6a5e1bf5, 0x6a684b3f, 0x6a727ac7, +0x6a7caa8d, 0x6a86da91, 0x6a910ad4, 0x6a9b3b56, 0x6aa56c15, 0x6aaf9d13, 0x6ab9ce50, 0x6ac3ffca, +0x6ace3183, 0x6ad8637b, 0x6ae295b0, 0x6aecc824, 0x6af6fad6, 0x6b012dc6, 0x6b0b60f4, 0x6b159461, +0x6b1fc80c, 0x6b29fbf5, 0x6b34301c, 0x6b3e6481, 0x6b489925, 0x6b52ce06, 0x6b5d0326, 0x6b673884, +0x6b716e20, 0x6b7ba3fa, 0x6b85da12, 0x6b901068, 0x6b9a46fd, 0x6ba47dcf, 0x6baeb4df, 0x6bb8ec2e, +0x6bc323ba, 0x6bcd5b85, 0x6bd7938d, 0x6be1cbd3, 0x6bec0458, 0x6bf63d1a, 0x6c00761a, 0x6c0aaf58, +0x6c14e8d4, 0x6c1f228e, 0x6c295c86, 0x6c3396bc, 0x6c3dd130, 0x6c480be1, 0x6c5246d1, 0x6c5c81fe, +0x6c66bd69, 0x6c70f912, 0x6c7b34f8, 0x6c85711d, 0x6c8fad7f, 0x6c99ea1f, 0x6ca426fd, 0x6cae6418, +0x6cb8a172, 0x6cc2df09, 0x6ccd1cdd, 0x6cd75af0, 0x6ce19940, 0x6cebd7ce, 0x6cf61699, 0x6d0055a2, +0x6d0a94e9, 0x6d14d46d, 0x6d1f142f, 0x6d29542f, 0x6d33946c, 0x6d3dd4e7, 0x6d4815a0, 0x6d525695, +0x6d5c97c9, 0x6d66d93a, 0x6d711ae9, 0x6d7b5cd5, 0x6d859eff, 0x6d8fe166, 0x6d9a240a, 0x6da466ec, +0x6daeaa0c, 0x6db8ed69, 0x6dc33104, 0x6dcd74db, 0x6dd7b8f1, 0x6de1fd44, 0x6dec41d4, 0x6df686a1, +0x6e00cbac, 0x6e0b10f5, 0x6e15567a, 0x6e1f9c3d, 0x6e29e23d, 0x6e34287b, 0x6e3e6ef6, 0x6e48b5ae, +0x6e52fca4, 0x6e5d43d7, 0x6e678b47, 0x6e71d2f4, 0x6e7c1adf, 0x6e866307, 0x6e90ab6c, 0x6e9af40e, +0x6ea53ced, 0x6eaf860a, 0x6eb9cf64, 0x6ec418fb, 0x6ece62cf, 0x6ed8ace0, 0x6ee2f72e, 0x6eed41ba, +0x6ef78c83, 0x6f01d788, 0x6f0c22cb, 0x6f166e4b, 0x6f20ba08, 0x6f2b0602, 0x6f355239, 0x6f3f9ead, +0x6f49eb5e, 0x6f54384d, 0x6f5e8578, 0x6f68d2e0, 0x6f732085, 0x6f7d6e67, 0x6f87bc86, 0x6f920ae2, +0x6f9c597b, 0x6fa6a851, 0x6fb0f763, 0x6fbb46b3, 0x6fc59640, 0x6fcfe609, 0x6fda360f, 0x6fe48652, +0x6feed6d2, 0x6ff9278f, 0x70037889, 0x700dc9bf, 0x70181b32, 0x70226ce3, 0x702cbecf, 0x703710f9, +0x7041635f, 0x704bb602, 0x705608e2, 0x70605bff, 0x706aaf58, 0x707502ee, 0x707f56c1, 0x7089aad0, +0x7093ff1c, 0x709e53a5, 0x70a8a86a, 0x70b2fd6c, 0x70bd52ab, 0x70c7a826, 0x70d1fdde, 0x70dc53d2, +0x70e6aa03, 0x70f10071, 0x70fb571b, 0x7105ae02, 0x71100525, 0x711a5c85, 0x7124b421, 0x712f0bfa, +0x7139640f, 0x7143bc61, 0x714e14ef, 0x71586dba, 0x7162c6c1, 0x716d2004, 0x71777984, 0x7181d341, +0x718c2d3a, 0x7196876f, 0x71a0e1e1, 0x71ab3c8f, 0x71b59779, 0x71bff2a0, 0x71ca4e03, 0x71d4a9a3, +0x71df057e, 0x71e96197, 0x71f3bdeb, 0x71fe1a7c, 0x72087749, 0x7212d452, 0x721d3197, 0x72278f19, +0x7231ecd7, 0x723c4ad1, 0x7246a908, 0x7251077b, 0x725b6629, 0x7265c514, 0x7270243c, 0x727a839f, +0x7284e33f, 0x728f431a, 0x7299a332, 0x72a40386, 0x72ae6416, 0x72b8c4e2, 0x72c325eb, 0x72cd872f, +0x72d7e8af, 0x72e24a6c, 0x72ecac64, 0x72f70e99, 0x73017109, 0x730bd3b6, 0x7316369f, 0x732099c3, +0x732afd24, 0x733560c0, 0x733fc499, 0x734a28ad, 0x73548cfe, 0x735ef18a, 0x73695652, 0x7373bb57, +0x737e2097, 0x73888613, 0x7392ebca, 0x739d51be, 0x73a7b7ee, 0x73b21e59, 0x73bc8500, 0x73c6ebe4, +0x73d15302, 0x73dbba5d, 0x73e621f4, 0x73f089c6, 0x73faf1d4, 0x74055a1e, 0x740fc2a3, 0x741a2b65, +0x74249462, 0x742efd9b, 0x7439670f, 0x7443d0bf, 0x744e3aab, 0x7458a4d3, 0x74630f36, 0x746d79d5, +0x7477e4af, 0x74824fc6, 0x748cbb17, 0x749726a5, 0x74a1926e, 0x74abfe73, 0x74b66ab3, 0x74c0d72f, +0x74cb43e6, 0x74d5b0d9, 0x74e01e07, 0x74ea8b71, 0x74f4f917, 0x74ff66f8, 0x7509d514, 0x7514436c, +0x751eb200, 0x752920cf, 0x75338fd9, 0x753dff1f, 0x75486ea1, 0x7552de5d, 0x755d4e56, 0x7567be89, +0x75722ef8, 0x757c9fa3, 0x75871089, 0x759181aa, 0x759bf306, 0x75a6649e, 0x75b0d671, 0x75bb4880, +0x75c5baca, 0x75d02d4f, 0x75daa00f, 0x75e5130b, 0x75ef8642, 0x75f9f9b4, 0x76046d62, 0x760ee14b, +0x7619556f, 0x7623c9ce, 0x762e3e68, 0x7638b33e, 0x7643284f, 0x764d9d9b, 0x76581322, 0x766288e4, +0x766cfee2, 0x7677751b, 0x7681eb8e, 0x768c623d, 0x7696d927, 0x76a1504d, 0x76abc7ad, 0x76b63f48, +0x76c0b71f, 0x76cb2f30, 0x76d5a77d, 0x76e02004, 0x76ea98c7, 0x76f511c4, 0x76ff8afd, 0x770a0471, +0x77147e1f, 0x771ef809, 0x7729722d, 0x7733ec8d, 0x773e6727, 0x7748e1fd, 0x77535d0d, 0x775dd858, +0x776853df, 0x7772cfa0, 0x777d4b9c, 0x7787c7d2, 0x77924444, 0x779cc0f1, 0x77a73dd8, 0x77b1bafa, +0x77bc3858, 0x77c6b5ef, 0x77d133c2, 0x77dbb1d0, 0x77e63018, 0x77f0ae9b, 0x77fb2d59, 0x7805ac52, +0x78102b85, 0x781aaaf3, 0x78252a9c, 0x782faa80, 0x783a2a9e, 0x7844aaf7, 0x784f2b8a, 0x7859ac59, +0x78642d62, 0x786eaea5, 0x78793024, 0x7883b1dd, 0x788e33d0, 0x7898b5fe, 0x78a33867, 0x78adbb0b, +0x78b83de9, 0x78c2c101, 0x78cd4454, 0x78d7c7e2, 0x78e24baa, 0x78eccfad, 0x78f753ea, 0x7901d862, +0x790c5d15, 0x7916e202, 0x79216729, 0x792bec8b, 0x79367227, 0x7940f7fe, 0x794b7e0f, 0x7956045b, +0x79608ae1, 0x796b11a1, 0x7975989c, 0x79801fd1, 0x798aa741, 0x79952eeb, 0x799fb6d0, 0x79aa3eee, +0x79b4c748, 0x79bf4fdb, 0x79c9d8a9, 0x79d461b1, 0x79deeaf4, 0x79e97470, 0x79f3fe27, 0x79fe8819, +0x7a091244, 0x7a139caa, 0x7a1e274a, 0x7a28b225, 0x7a333d39, 0x7a3dc888, 0x7a485411, 0x7a52dfd4, +0x7a5d6bd2, 0x7a67f809, 0x7a72847b, 0x7a7d1127, 0x7a879e0d, 0x7a922b2e, 0x7a9cb888, 0x7aa7461d, +0x7ab1d3eb, 0x7abc61f4, 0x7ac6f037, 0x7ad17eb4, 0x7adc0d6b, 0x7ae69c5c, 0x7af12b87, 0x7afbbaec, +0x7b064a8b, 0x7b10da64, 0x7b1b6a78, 0x7b25fac5, 0x7b308b4c, 0x7b3b1c0e, 0x7b45ad09, 0x7b503e3e, +0x7b5acfad, 0x7b656156, 0x7b6ff339, 0x7b7a8556, 0x7b8517ad, 0x7b8faa3e, 0x7b9a3d09, 0x7ba4d00d, +0x7baf634c, 0x7bb9f6c4, 0x7bc48a76, 0x7bcf1e62, 0x7bd9b288, 0x7be446e8, 0x7beedb82, 0x7bf97055, +0x7c040562, 0x7c0e9aa9, 0x7c19302a, 0x7c23c5e5, 0x7c2e5bd9, 0x7c38f207, 0x7c43886f, 0x7c4e1f10, +0x7c58b5ec, 0x7c634d01, 0x7c6de450, 0x7c787bd8, 0x7c83139a, 0x7c8dab96, 0x7c9843cb, 0x7ca2dc3a, +0x7cad74e3, 0x7cb80dc6, 0x7cc2a6e2, 0x7ccd4037, 0x7cd7d9c7, 0x7ce27390, 0x7ced0d92, 0x7cf7a7ce, +0x7d024244, 0x7d0cdcf3, 0x7d1777dc, 0x7d2212fe, 0x7d2cae5a, 0x7d3749ef, 0x7d41e5be, 0x7d4c81c7, +0x7d571e08, 0x7d61ba84, 0x7d6c5739, 0x7d76f427, 0x7d81914f, 0x7d8c2eb0, 0x7d96cc4b, 0x7da16a1f, +0x7dac082d, 0x7db6a673, 0x7dc144f4, 0x7dcbe3ae, 0x7dd682a1, 0x7de121cd, 0x7debc133, 0x7df660d2, +0x7e0100ab, 0x7e0ba0bd, 0x7e164108, 0x7e20e18d, 0x7e2b824b, 0x7e362342, 0x7e40c472, 0x7e4b65dc, +0x7e56077f, 0x7e60a95b, 0x7e6b4b71, 0x7e75edc0, 0x7e809048, 0x7e8b3309, 0x7e95d603, 0x7ea07937, +0x7eab1ca4, 0x7eb5c04a, 0x7ec06429, 0x7ecb0842, 0x7ed5ac93, 0x7ee0511e, 0x7eeaf5e2, 0x7ef59adf, +0x7f004015, 0x7f0ae584, 0x7f158b2c, 0x7f20310e, 0x7f2ad728, 0x7f357d7c, 0x7f402409, 0x7f4acace, +0x7f5571cd, 0x7f601905, 0x7f6ac076, 0x7f75681f, 0x7f801002, 0x7f8ab81e, 0x7f956073, 0x7fa00901, +0x7faab1c7, 0x7fb55ac7, 0x7fc00400, 0x7fcaad71, 0x7fd5571c, 0x7fe00100, 0x7feaab1c, 0x7ff55571, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, +0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_aa_cs_data[] = { +0x00006dc2, 0x000070dc, 0x0000798d, 0x00007ddd, 0x00007f6d, 0x00007fe4, 0x00007ffc, 0x00007fff,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_aa_ca_data[] = { +0xffffbe26, 0xffffc39f, 0xffffd7e4, 0xffffe8b8, 0xfffff3e5, 0xfffffac2, 0xfffffe2f, 0xffffff87,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_win_data[] = { +0x00000421, 0x00000db8, 0x000019c7, 0x000029ad, 0x00003fff, 0x00006246, 0x00009ee0, 0x00012a7d, +0x0003df40, 0xfffbc63e, 0xfffe7b01, 0xffff069e, 0xffff4338, 0xffff657e, 0xffff7bd0, 0xffff8bb6, +0xffff97c5, 0xffffa15c, 0xffffa947, 0xffffb006, 0xffffb5eb, 0xffffbb30, 0xffffc000, 0xffffc47a, +0xffffc8b7, 0xffffccca, 0xffffd0c5, 0xffffd4b9, 0xffffd8b4, 0xffffdcc8, 0xffffe104, 0xffffe57e, +0xffffea4e, 0xffffef94, 0xfffff579, 0xfffffc37, 0x00000421, 0x00000db8, 0x000019c7, 0x000029ad, +0x00003fff, 0x00006246, 0x00009ee0, 0x00012a7d, 0x0003df40, 0xfffbc63e, 0xfffe7b01, 0xffff069e, +0xffff4338, 0xffff657e, 0xffff7bd0, 0xffff8bb6, 0xffff97c5, 0xffffa15c, 0xffffa932, 0xffffaf55, +0xffffb41e, 0xffffb7d9, 0xffffbabb, 0xffffbce5, 0xffffbf02, 0xffffc45d, 0xffffcd2e, 0xffffd901, +0xffffe74d, 0xfffff772, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000db8, 0x00003fff, 0x00012a7d, 0xfffe7b01, 0xffff657e, 0xffff97c5, 0xffffb006, 0xffffc000, +0xffffccca, 0xffffd8b4, 0xffffe57e, 0xfffff579, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00002698, 0x0000bba3, 0x00037d32, 0xfffb73f7, 0xfffe3b01, 0xfffedad6, +0xffff2b2b, 0xffff58c3, 0xffff7566, 0xffff88e3, 0xffff96df, 0xffffa145, 0xffffa947, 0xffffb006, +0xffffb5eb, 0xffffbb30, 0xffffc000, 0xffffc47a, 0xffffc8b7, 0xffffccca, 0xffffd0c5, 0xffffd4b9, +0xffffd8b4, 0xffffdcc8, 0xffffe104, 0xffffe57e, 0xffffea4e, 0xffffef94, 0xfffff579, 0xfffffc37,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_COS9_data[] = { +0x00008000, 0x00007e0e, 0x00007847, 0x00006ed9, 0x0000620d, 0x00005246, 0x00004000, 0x00002bc7, +0x0000163a,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_tfcos36_data[] = { +0x0000403e, 0x00004241, 0x0000469d, 0x00004e21, 0x00005a82, 0x00006f94, 0x0000976f, 0x0000f746, +0x0002de51,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_tfcos12_data[] = { +0x00004241, 0x00005a82, 0x0000f746,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_cos9_data[] = { +0x00007847, 0xffffe9c6, 0xffff9df3,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_cos18_data[] = { +0x00007e0e, 0xffffd439, 0xffffadba,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_COS1_data[] = { +0x00004deb, 0xffff89bf, 0xffffef4b, 0x00007ee7, 0xffffcf05, 0xffff9a74, 0x000030fb, 0xffff89bf, +0x00007641, 0xffffcf05, 0xffffcf05, 0x00007641, 0x000010b5, 0xffffcf05, 0x00004deb, 0xffff9a74, +0x00007641, 0xffff8119, 0xffffef4b, 0x000030fb, 0xffffb215, 0x0000658c, 0xffff89bf, 0x00007ee7, +0xffffcf05, 0x00007641, 0xffff89bf, 0x000030fb, 0x000030fb, 0xffff89bf, 0xffffb215, 0x00007641, +0x000010b5, 0xffff8119, 0x000030fb, 0x0000658c, 0xffff9a74, 0x000030fb, 0x00007ee7, 0x000010b5, +0xffff89bf, 0xffffb215, 0xffff89bf, 0xffffcf05, 0x000030fb, 0x00007641, 0x00007641, 0x000030fb, +0xffff8119, 0xffff89bf, 0xffff9a74, 0xffffb215, 0xffffcf05, 0xffffef4b, 0xffff8119, 0xffff89bf, +0xffff9a74, 0xffffb215, 0xffffcf05, 0xffffef4b, 0xffff89bf, 0xffffcf05, 0x000030fb, 0x00007641, +0x00007641, 0x000030fb, 0xffff9a74, 0x000030fb, 0x00007ee7, 0x000010b5, 0xffff89bf, 0xffffb215,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_win1_data[] = { +0x00000421, 0xfffff248, 0x000019c7, 0xffffd653, 0x00003fff, 0xffff9dba, 0x00009ee0, 0xfffed583, +0x0003df40, 0x000439c2, 0xfffe7b01, 0x0000f962, 0xffff4338, 0x00009a82, 0xffff7bd0, 0x0000744a, +0xffff97c5, 0x00005ea4, 0xffffa947, 0x00004ffa, 0xffffb5eb, 0x000044d0, 0xffffc000, 0x00003b86, +0xffffc8b7, 0x00003336, 0xffffd0c5, 0x00002b47, 0xffffd8b4, 0x00002338, 0xffffe104, 0x00001a82, +0xffffea4e, 0x0000106c, 0xfffff579, 0x000003c9, 0x00000421, 0xfffff248, 0x000019c7, 0xffffd653, +0x00003fff, 0xffff9dba, 0x00009ee0, 0xfffed583, 0x0003df40, 0x000439c2, 0xfffe7b01, 0x0000f962, +0xffff4338, 0x00009a82, 0xffff7bd0, 0x0000744a, 0xffff97c5, 0x00005ea4, 0xffffa932, 0x000050ab, +0xffffb41e, 0x00004827, 0xffffbabb, 0x0000431b, 0xffffbf02, 0x00003ba3, 0xffffcd2e, 0x000026ff, +0xffffe74d, 0x0000088e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000db8, 0xffffc001, 0x00012a7d, 0x000184ff, 0xffff657e, 0x0000683b, 0xffffb006, 0x00004000, +0xffffccca, 0x0000274c, 0xffffe57e, 0x00000a87, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00002698, 0xffff445d, 0x00037d32, 0x00048c09, 0xfffe3b01, 0x0001252a, +0xffff2b2b, 0x0000a73d, 0xffff7566, 0x0000771d, 0xffff96df, 0x00005ebb, 0xffffa947, 0x00004ffa, +0xffffb5eb, 0x000044d0, 0xffffc000, 0x00003b86, 0xffffc8b7, 0x00003336, 0xffffd0c5, 0x00002b47, +0xffffd8b4, 0x00002338, 0xffffe104, 0x00001a82, 0xffffea4e, 0x0000106c, 0xfffff579, 0x000003c9,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_tan1_1_data[] = { +0x00000000, 0x00001b0c, 0x00002ed9, 0x00003fff, 0x00005126, 0x000064f3, 0x00007fff, 0x0000aed9, +0x00012ed9, 0x7fffffff, 0xffff5127, 0xffffd127, 0x00000000, 0x00001b0c, 0x00002ed9, 0x00003fff,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_tan2_1_data[] = { +0x00008000, 0x000064f3, 0x00005126, 0x00004000, 0x00002ed9, 0x00001b0c, 0x00000000, 0xffffd127, +0xffff5127, 0x80000000, 0x00012ed9, 0x0000aed9, 0x00008000, 0x000064f3, 0x00005126, 0x00004000,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_tan1_2_data[] = { +0x00000000, 0x00002640, 0x00004241, 0x00005a82, 0x000072c2, 0x00008ec3, 0x0000b504, 0x0000f746, +0x0001ac4b, 0x7fffffff, 0xffff08ba, 0xffffbdbf, 0x00000000, 0x00002640, 0x00004241, 0x00005a82,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_tan2_2_data[] = { +0x0000b504, 0x00008ec3, 0x000072c2, 0x00005a82, 0x00004241, 0x00002640, 0x00000000, 0xffffbdbf, +0xffff08ba, 0x80000000, 0x0001ac4b, 0x0000f746, 0x0000b504, 0x00008ec3, 0x000072c2, 0x00005a82,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_pow1_1_data[] = { +0x00008000, 0x00006ba2, 0x00008000, 0x00005a82, 0x00008000, 0x00004c1b, 0x00008000, 0x00004000, +0x00008000, 0x000035d1, 0x00008000, 0x00002d41, 0x00008000, 0x0000260d, 0x00008000, 0x00002000, +0x00008000, 0x00005a82, 0x00008000, 0x00003fff, 0x00008000, 0x00002d41, 0x00008000, 0x00001fff, +0x00008000, 0x000016a0, 0x00008000, 0x00000fff, 0x00008000, 0x00000b50, 0x00008000, 0x000007ff,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_pow2_1_data[] = { +0x00008000, 0x00008000, 0x00006ba2, 0x00008000, 0x00005a82, 0x00008000, 0x00004c1b, 0x00008000, +0x00004000, 0x00008000, 0x000035d1, 0x00008000, 0x00002d41, 0x00008000, 0x0000260d, 0x00008000, +0x00008000, 0x00008000, 0x00005a82, 0x00008000, 0x00003fff, 0x00008000, 0x00002d41, 0x00008000, +0x00001fff, 0x00008000, 0x000016a0, 0x00008000, 0x00000fff, 0x00008000, 0x00000b50, 0x00008000,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_pow1_2_data[] = { +0x0000b504, 0x00009837, 0x0000b504, 0x00008000, 0x0000b504, 0x00006ba2, 0x0000b504, 0x00005a82, +0x0000b504, 0x00004c1b, 0x0000b504, 0x00004000, 0x0000b504, 0x000035d1, 0x0000b504, 0x00002d41, +0x0000b504, 0x00008000, 0x0000b504, 0x00005a82, 0x0000b504, 0x00003fff, 0x0000b504, 0x00002d41, +0x0000b504, 0x00001fff, 0x0000b504, 0x000016a0, 0x0000b504, 0x00000fff, 0x0000b504, 0x00000b50,}; +#endif +#ifdef USE_DATA_TABLES +static long mpeg3_pow2_2_data[] = { +0x0000b504, 0x0000b504, 0x00009837, 0x0000b504, 0x00008000, 0x0000b504, 0x00006ba2, 0x0000b504, +0x00005a82, 0x0000b504, 0x00004c1b, 0x0000b504, 0x00004000, 0x0000b504, 0x000035d1, 0x0000b504, +0x0000b504, 0x0000b504, 0x00008000, 0x0000b504, 0x00005a82, 0x0000b504, 0x00003fff, 0x0000b504, +0x00002d41, 0x0000b504, 0x00001fff, 0x0000b504, 0x000016a0, 0x0000b504, 0x00000fff, 0x0000b504,}; +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/audio/header.c b/core/multimedia/opieplayer/libmpeg3/audio/header.c new file mode 100644 index 0000000..02b5e7c --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/header.c @@ -0,0 +1,163 @@ +#include "mpeg3audio.h" +#include "tables.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" + +#include + +/* Return 1 if the head check doesn't find a header. */ +int mpeg3audio_head_check(unsigned long head) +{ + if((head & 0xffe00000) != 0xffe00000) return 1; + if(!((head >> 17) & 3)) return 1; + if(((head >> 12) & 0xf) == 0xf) return 1; + if(!((head >> 12) & 0xf)) return 1; + if(((head >> 10) & 0x3) == 0x3 ) return 1; + if(((head >> 19) & 1) == 1 && ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1) + return 1; + if((head & 0xffff0000) == 0xfffe0000) return 1; + + return 0; +} + +int mpeg3audio_decode_header(mpeg3audio_t *audio) +{ + if(audio->newhead & (1 << 20)) + { + audio->lsf = (audio->newhead & (1 << 19)) ? 0x0 : 0x1; + audio->mpeg35 = 0; + } + else + { + audio->lsf = 1; + audio->mpeg35 = 1; + } + + audio->layer = 4 - ((audio->newhead >> 17) & 3); + if(audio->mpeg35) + audio->sampling_frequency_code = 6 + ((audio->newhead >> 10) & 0x3); + else + audio->sampling_frequency_code = ((audio->newhead >> 10) & 0x3) + (audio->lsf * 3); + + audio->error_protection = ((audio->newhead >> 16) & 0x1) ^ 0x1; + + audio->bitrate_index = ((audio->newhead >> 12) & 0xf); + audio->padding = ((audio->newhead >> 9) & 0x1); + audio->extension = ((audio->newhead >> 8) & 0x1); + audio->mode = ((audio->newhead >> 6) & 0x3); + audio->mode_ext = ((audio->newhead >> 4) & 0x3); + audio->copyright = ((audio->newhead >> 3) & 0x1); + audio->original = ((audio->newhead >> 2) & 0x1); + audio->emphasis = audio->newhead & 0x3; + audio->channels = (audio->mode == MPG_MD_MONO) ? 1 : 2; + if(audio->channels > 1) + audio->single = -1; + else + audio->single = 3; + + audio->prev_framesize = audio->framesize; + + if(!audio->bitrate_index) return 1; + audio->bitrate = 1000 * mpeg3_tabsel_123[audio->lsf][audio->layer - 1][audio->bitrate_index]; + + switch(audio->layer) + { + case 1: + audio->framesize = (long)mpeg3_tabsel_123[audio->lsf][0][audio->bitrate_index] * 12000; + audio->framesize /= mpeg3_freqs[audio->sampling_frequency_code]; + audio->framesize = ((audio->framesize + audio->padding) << 2) - 4; + break; + case 2: + audio->framesize = (long)mpeg3_tabsel_123[audio->lsf][1][audio->bitrate_index] * 144000; + audio->framesize /= mpeg3_freqs[audio->sampling_frequency_code]; + audio->framesize += audio->padding - 4; + break; + case 3: + if(audio->lsf) + audio->ssize = (audio->channels == 1) ? 9 : 17; + else + audio->ssize = (audio->channels == 1) ? 17 : 32; + if(audio->error_protection) + audio->ssize += 2; + audio->framesize = (long)mpeg3_tabsel_123[audio->lsf][2][audio->bitrate_index] * 144000; + audio->framesize /= mpeg3_freqs[audio->sampling_frequency_code] << (audio->lsf); + audio->framesize = audio->framesize + audio->padding - 4; + break; + default: + return 1; + } + + if(audio->framesize > MAXFRAMESIZE) return 1; + + return 0; +} + +int mpeg3audio_read_frame_body(mpeg3audio_t *audio) +{ + int i; + for(i = 0; i < audio->framesize; i++) + { + audio->bsbuf[i] = mpeg3bits_getbits(audio->astream, 8); + } + return 0; +} + +/* Seek to the start of the previous header */ +int mpeg3audio_prev_header(mpeg3audio_t *audio) +{ + int result = 0, i, len = (int)audio->avg_framesize; + + for(i = 0; i < len && !result; i++) + { + mpeg3bits_getbits_reverse(audio->astream, 8); + } +/* Get reading in the forward direction again. */ + result |= mpeg3bits_refill(audio->astream); + return result; +} + +/* Read the next header */ +int mpeg3audio_read_header(mpeg3audio_t *audio) +{ + unsigned int code; + int i; + int attempt = 0; + int result = 0; + + switch(audio->format) + { + case AUDIO_AC3: + result = mpeg3audio_read_ac3_header(audio); + break; + + case AUDIO_MPEG: +/* Layer 1 not supported */ + if(audio->layer == 1) + { + fprintf(stderr, "mpeg3audio_new: layer 1 not supported\n"); + result = 1; + } + audio->newhead = mpeg3bits_showbits(audio->astream, 32); + if(!mpeg3bits_eof(audio->astream) && + (mpeg3audio_head_check(audio->newhead) || mpeg3audio_decode_header(audio))) + { + do + { + attempt++; + mpeg3bits_getbyte_noptr(audio->astream); + audio->newhead = mpeg3bits_showbits(audio->astream, 32); + }while(!mpeg3bits_eof(audio->astream) && + attempt < 65536 && + (mpeg3audio_head_check(audio->newhead) || mpeg3audio_decode_header(audio))); + } + +/* Skip the 4 bytes containing the header */ + mpeg3bits_getbits(audio->astream, 32); + break; + + case AUDIO_PCM: + mpeg3audio_read_pcm_header(audio); + break; + } + return mpeg3bits_eof(audio->astream); +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/huffman.h b/core/multimedia/opieplayer/libmpeg3/audio/huffman.h new file mode 100644 index 0000000..a9c8fff --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/huffman.h @@ -0,0 +1,355 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef HUFFMAN_H +#define HUFFMAN_H + +/* + * huffman tables ... recalcualted to work with my optimzed + * decoder scheme (MH) + * + * probably we could save a few bytes of memory, because the + * smaller tables are often the part of a bigger table + */ + +struct newhuff +{ + unsigned int linbits; + short *table; +}; + +static short mpeg3_tab0[] = +{ + 0 +}; + +static short mpeg3_tab1[] = +{ + -5, -3, -1, 17, 1, 16, 0 +}; + +static short mpeg3_tab2[] = +{ + -15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1, + 16, 0 +}; + +static short mpeg3_tab3[] = +{ + -13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1, + 1, 0 +}; + +static short mpeg3_tab5[] = +{ + -29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19, + 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16, + 0 +}; + +static short mpeg3_tab6[] = +{ + -25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19, + 49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16, + 0 +}; + +static short mpeg3_tab7[] = +{ + -69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83, + -1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1, + 80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7, + -3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18, + -5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0 +}; + +static short mpeg3_tab8[] = +{ + -65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83, + -3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52, + 67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4, + 64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1, + 2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0 +}; + +static short mpeg3_tab9[] = +{ + -63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1, + 84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67, + -1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5, + -3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2, + 18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0 +}; + +static short mpeg3_tab10[] = +{ +-125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118, + 87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3, + -1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1, + 100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23, + -17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81, + -1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7, + -3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1, + 50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1, + 2, 32, 17, -1, 1, 16, 0 +}; + +static short mpeg3_tab11[] = +{ +-121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117, + -3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55, + -1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114, + -1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96, + -1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38, + 6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1, + 36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50, + -1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2, + 32, 17, -3, -1, 1, 16, 0 +}; + +static short mpeg3_tab12[] = +{ +-115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87, + 117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115, + 85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7, + 112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5, + -1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37, + 82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4, + 36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3, + -1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1, + 2, 32, 0, 17, -1, 1, 16 +}; + +static short mpeg3_tab13[] = +{ +-509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9, + -7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238, + 207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1, + 236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249, + 234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158, + -5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1, + 203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245, + 231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1, + 63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15, + -5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1, + 200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1, + 240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1, + 46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3, + -1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1, + 198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5, + -1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167, + 151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76, + 196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137, + 28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106, + -5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43, + -1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178, + -11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1, + 58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161, + -3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88, + -1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1, + 131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25, + 145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100, + 40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113, + -1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38, + -1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6, + 96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81, + -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11, + -5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3, + -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16, + 0 +}; + +static short mpeg3_tab15[] = +{ +-495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239, + -1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237, + 191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3, + -1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219, + -3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173, + -3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246, + -3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9, + -3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243, + 216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1, + 31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1, + 125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3, + -1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5, + -1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124, + 199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1, + 198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183, + -5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76, + -1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1, + 122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15, + -7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106, + -5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5, + -1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74, + -1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1, + 42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134, + 73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29, + -13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7, + -3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7, + -3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86, + -3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100, + 23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69, + -1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9, + -5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1, + 5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20, + 4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48, + 34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16, + 0 +}; + +static short mpeg3_tab16[] = +{ +-509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223, + 253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3, + -1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5, + -3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19, + -13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1, + 238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5, + -1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125, + 94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13, + -5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3, + -1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186, + -1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1, + 214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169, + -5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213, + -3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154, + 108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1, + 153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1, + 192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45, + -1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107, + -1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12, + -1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1, + 178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74, + 164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33, + -19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3, + -1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147, + -1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1, + 145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3, + -1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1, + 8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3, + -1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1, + 99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9, + -5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33, + -23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, + -5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1, + 3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16, + 0 +}; + +static short mpeg3_tab24[] = +{ +-451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1, + 207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9, + -5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79, + 244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31, + 240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1, + 236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3, + -1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3, + -1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235, +-143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3, + -1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9, + -5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1, + 78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185, + 170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199, + 77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3, + -1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3, + -1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196, + -3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1, + 167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1, + 137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10, + 26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9, + 144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165, + 27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135, + -1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104, + -1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3, + -1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3, + -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7, + -3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86, + 101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15, + -7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84, + -7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1, + 83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5, + 80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5, + -1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1, + 3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16, + 0 +}; + +static short mpeg3_tab_c0[] = +{ + -29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5, + 9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8, + 0 +}; + +static short mpeg3_tab_c1[] = +{ + -15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9, + 8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1, + 0 +}; + + + +static struct newhuff mpeg3_ht[] = +{ + { /* 0 */ 0 , mpeg3_tab0 } , + { /* 2 */ 0 , mpeg3_tab1 } , + { /* 3 */ 0 , mpeg3_tab2 } , + { /* 3 */ 0 , mpeg3_tab3 } , + { /* 0 */ 0 , mpeg3_tab0 } , + { /* 4 */ 0 , mpeg3_tab5 } , + { /* 4 */ 0 , mpeg3_tab6 } , + { /* 6 */ 0 , mpeg3_tab7 } , + { /* 6 */ 0 , mpeg3_tab8 } , + { /* 6 */ 0 , mpeg3_tab9 } , + { /* 8 */ 0 , mpeg3_tab10 } , + { /* 8 */ 0 , mpeg3_tab11 } , + { /* 8 */ 0 , mpeg3_tab12 } , + { /* 16 */ 0 , mpeg3_tab13 } , + { /* 0 */ 0 , mpeg3_tab0 } , + { /* 16 */ 0 , mpeg3_tab15 } , + + { /* 16 */ 1 , mpeg3_tab16 } , + { /* 16 */ 2 , mpeg3_tab16 } , + { /* 16 */ 3 , mpeg3_tab16 } , + { /* 16 */ 4 , mpeg3_tab16 } , + { /* 16 */ 6 , mpeg3_tab16 } , + { /* 16 */ 8 , mpeg3_tab16 } , + { /* 16 */ 10, mpeg3_tab16 } , + { /* 16 */ 13, mpeg3_tab16 } , + { /* 16 */ 4 , mpeg3_tab24 } , + { /* 16 */ 5 , mpeg3_tab24 } , + { /* 16 */ 6 , mpeg3_tab24 } , + { /* 16 */ 7 , mpeg3_tab24 } , + { /* 16 */ 8 , mpeg3_tab24 } , + { /* 16 */ 9 , mpeg3_tab24 } , + { /* 16 */ 11, mpeg3_tab24 } , + { /* 16 */ 13, mpeg3_tab24 } +}; + +static struct newhuff mpeg3_htc[] = +{ + { /* 1 , 1 , */ 0 , mpeg3_tab_c0 } , + { /* 1 , 1 , */ 0 , mpeg3_tab_c1 } +}; + + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/audio/layer1.c b/core/multimedia/opieplayer/libmpeg3/audio/layer1.c new file mode 100644 index 0000000..0c355f3 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/layer1.c @@ -0,0 +1,6 @@ +#include "mpeg3audio.h" + +int mpeg3audio_dolayer1(mpeg3audio_t *audio) +{ + ; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/layer2.c b/core/multimedia/opieplayer/libmpeg3/audio/layer2.c new file mode 100644 index 0000000..01582fe --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/layer2.c @@ -0,0 +1,418 @@ +/* + * most other tables are calculated on program start (which is (of course) + * not ISO-conform) .. + * Layer-3 huffman table is in huffman.h + */ + +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "tables.h" + +struct al_table alloc_0[] = { + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767} }; + +struct al_table alloc_1[] = { + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511}, + {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767}, + {2,0},{5,3},{7,5},{16,-32767} }; + +struct al_table alloc_2[] = { + {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255}, + {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383}, + {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255}, + {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} }; + +struct al_table alloc_3[] = { + {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255}, + {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383}, + {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255}, + {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} }; + +struct al_table alloc_4[] = { + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191}, + {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127}, + {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9}, + {2,0},{5,3},{7,5},{10,9} }; + + +int mpeg3audio_II_select_table(mpeg3audio_t *audio) +{ + static int translate[3][2][16] = + {{{ 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0}, + { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0}}, + {{ 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0}, + { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0}}, + {{ 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0}, + { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0}}}; + int table, sblim; + static struct al_table *tables[5] = + {alloc_0, alloc_1, alloc_2, alloc_3, alloc_4}; + static int sblims[5] = {27, 30, 8, 12, 30}; + + if(audio->lsf) + table = 4; + else + table = translate[audio->sampling_frequency_code][2 - audio->channels][audio->bitrate_index]; + sblim = sblims[table]; + + audio->alloc = tables[table]; + audio->II_sblimit = sblim; + return 0; +} + +int mpeg3audio_II_step_one(mpeg3audio_t *audio, unsigned int *bit_alloc, int *scale) +{ + int stereo = audio->channels - 1; + int sblimit = audio->II_sblimit; + int jsbound = audio->jsbound; + int sblimit2 = audio->II_sblimit << stereo; + struct al_table *alloc1 = audio->alloc; + int i, result = 0; + unsigned int *scfsi_buf = audio->layer2_scfsi_buf; + unsigned int *scfsi, *bita; + int sc, step; + + bita = bit_alloc; + if(stereo) + { +/* Stereo */ + for(i = jsbound;i ; i--, alloc1 += (1 << step)) + { + *bita++ = (char)mpeg3bits_getbits(audio->astream, step = alloc1->bits); + *bita++ = (char)mpeg3bits_getbits(audio->astream, step); + } + for(i = sblimit-jsbound; i; i--, alloc1 += (1 << step)) + { + bita[0] = (char)mpeg3bits_getbits(audio->astream, step = alloc1->bits); + bita[1] = bita[0]; + bita += 2; + } + bita = bit_alloc; + scfsi = scfsi_buf; + for(i = sblimit2; i; i--) + if(*bita++) *scfsi++ = (char)mpeg3bits_getbits(audio->astream, 2); + } + else + { +/* mono */ + for(i = sblimit; i; i--, alloc1 += (1 << step)) + *bita++ = (char)mpeg3bits_getbits(audio->astream, step = alloc1->bits); + bita = bit_alloc; + scfsi = scfsi_buf; + for(i = sblimit; i; i--) if (*bita++) *scfsi++ = (char)mpeg3bits_getbits(audio->astream, 2); + } + + bita = bit_alloc; + scfsi = scfsi_buf; + for(i = sblimit2; i; i--) + { + if(*bita++) + switch(*scfsi++) + { + case 0: + *scale++ = mpeg3bits_getbits(audio->astream, 6); + *scale++ = mpeg3bits_getbits(audio->astream, 6); + *scale++ = mpeg3bits_getbits(audio->astream, 6); + break; + case 1 : + *scale++ = sc = mpeg3bits_getbits(audio->astream, 6); + *scale++ = sc; + *scale++ = mpeg3bits_getbits(audio->astream, 6); + break; + case 2: + *scale++ = sc = mpeg3bits_getbits(audio->astream, 6); + *scale++ = sc; + *scale++ = sc; + break; + default: /* case 3 */ + *scale++ = mpeg3bits_getbits(audio->astream, 6); + *scale++ = sc = mpeg3bits_getbits(audio->astream, 6); + *scale++ = sc; + break; + } + } + return result | mpeg3bits_error(audio->astream); +} + +int mpeg3audio_II_step_two(mpeg3audio_t *audio, unsigned int *bit_alloc, mpeg3_real_t fraction[2][4][SBLIMIT], int *scale, int x1) +{ + int i, j, k, ba, result = 0; + int channels = audio->channels; + int sblimit = audio->II_sblimit; + int jsbound = audio->jsbound; + struct al_table *alloc2, *alloc1 = audio->alloc; + unsigned int *bita = bit_alloc; + int d1, step, test; + + for(i = 0; i < jsbound; i++, alloc1 += (1 << step)) + { + step = alloc1->bits; + for(j = 0; j < channels; j++) + { + if(ba = *bita++) + { + k = (alloc2 = alloc1 + ba)->bits; + if((d1 = alloc2->d) < 0) + { + mpeg3_real_t cm = mpeg3_muls[k][scale[x1]]; + + fraction[j][0][i] = ((mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm; + fraction[j][1][i] = ((mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm; + fraction[j][2][i] = ((mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm; + } + else + { + static int *table[] = + {0, 0, 0, mpeg3_grp_3tab, 0, mpeg3_grp_5tab, 0, 0, 0, mpeg3_grp_9tab}; + unsigned int idx, *tab, m = scale[x1]; + + idx = (unsigned int)mpeg3bits_getbits(audio->astream, k); + tab = (unsigned int*)(table[d1] + idx + idx + idx); + fraction[j][0][i] = mpeg3_muls[*tab++][m]; + fraction[j][1][i] = mpeg3_muls[*tab++][m]; + fraction[j][2][i] = mpeg3_muls[*tab][m]; + } + scale += 3; + } + else + fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0; + } + } + + for(i = jsbound; i < sblimit; i++, alloc1 += (1 << step)) + { + step = alloc1->bits; +/* channel 1 and channel 2 bitalloc are the same */ + bita++; + if((ba = *bita++)) + { + k=(alloc2 = alloc1+ba)->bits; + if((d1 = alloc2->d) < 0) + { + mpeg3_real_t cm; + + cm = mpeg3_muls[k][scale[x1 + 3]]; + fraction[1][0][i] = (fraction[0][0][i] = (mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm; + fraction[1][1][i] = (fraction[0][1][i] = (mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm; + fraction[1][2][i] = (fraction[0][2][i] = (mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm; + cm = mpeg3_muls[k][scale[x1]]; + fraction[0][0][i] *= cm; + fraction[0][1][i] *= cm; + fraction[0][2][i] *= cm; + } + else + { + static int *table[] = {0, 0, 0, mpeg3_grp_3tab, 0, mpeg3_grp_5tab, 0, 0, 0, mpeg3_grp_9tab}; + unsigned int idx, *tab, m1, m2; + + m1 = scale[x1]; + m2 = scale[x1+3]; + idx = (unsigned int)mpeg3bits_getbits(audio->astream, k); + tab = (unsigned int*)(table[d1] + idx + idx + idx); + fraction[0][0][i] = mpeg3_muls[*tab][m1]; + fraction[1][0][i] = mpeg3_muls[*tab++][m2]; + fraction[0][1][i] = mpeg3_muls[*tab][m1]; + fraction[1][1][i] = mpeg3_muls[*tab++][m2]; + fraction[0][2][i] = mpeg3_muls[*tab][m1]; + fraction[1][2][i] = mpeg3_muls[*tab][m2]; + } + scale += 6; + } + else + { + fraction[0][0][i] = fraction[0][1][i] = fraction[0][2][i] = + fraction[1][0][i] = fraction[1][1][i] = fraction[1][2][i] = 0.0; + } +/* + should we use individual scalefac for channel 2 or + is the current way the right one , where we just copy channel 1 to + channel 2 ?? + The current 'strange' thing is, that we throw away the scalefac + values for the second channel ...!! +-> changed .. now we use the scalefac values of channel one !! +*/ + } + + if(sblimit > SBLIMIT) sblimit = SBLIMIT; + + for(i = sblimit; i < SBLIMIT; i++) + for(j = 0; j < channels; j++) + fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0; + + return result | mpeg3bits_error(audio->astream); +} + +int mpeg3audio_dolayer2(mpeg3audio_t *audio) +{ + int i, j, result = 0; + int channels = audio->channels; + mpeg3_real_t fraction[2][4][SBLIMIT]; /* pick_table clears unused subbands */ + unsigned int bit_alloc[64]; + int scale[192]; + int single = audio->single; + + if(audio->error_protection) + mpeg3bits_getbits(audio->astream, 16); + + mpeg3audio_II_select_table(audio); + + audio->jsbound = (audio->mode == MPG_MD_JOINT_STEREO) ? + (audio->mode_ext << 2) + 4 : audio->II_sblimit; + + if(channels == 1 || single == 3) + single = 0; + + result |= mpeg3audio_II_step_one(audio, bit_alloc, scale); + + for(i = 0; i < SCALE_BLOCK && !result; i++) + { + result |= mpeg3audio_II_step_two(audio, bit_alloc, fraction, scale, i >> 2); + + for(j = 0; j < 3; j++) + { + if(single >= 0) + { +/* Monaural */ + mpeg3audio_synth_mono(audio, fraction[single][j], audio->pcm_sample, &(audio->pcm_point)); + } + else + { +/* Stereo */ + int p1 = audio->pcm_point; + mpeg3audio_synth_stereo(audio, fraction[0][j], 0, audio->pcm_sample, &p1); + mpeg3audio_synth_stereo(audio, fraction[1][j], 1, audio->pcm_sample, &(audio->pcm_point)); + } + + if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels) + { +/* Need more room */ + mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels); + } + } + } + + + return result; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/layer3.c b/core/multimedia/opieplayer/libmpeg3/audio/layer3.c new file mode 100644 index 0000000..b8a5f06 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/layer3.c @@ -0,0 +1,1254 @@ +#include "huffman.h" +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "tables.h" + +#include +#include + +struct gr_info_s { + int scfsi; + unsigned part2_3_length; + unsigned big_values; + unsigned scalefac_compress; + unsigned block_type; + unsigned mixed_block_flag; + unsigned table_select[3]; + unsigned subblock_gain[3]; + unsigned maxband[3]; + unsigned maxbandl; + unsigned maxb; + unsigned region1start; + unsigned region2start; + unsigned preflag; + unsigned scalefac_scale; + unsigned count1table_select; + mpeg3_real_t *full_gain[3]; + mpeg3_real_t *pow2gain; +}; + +struct mpeg3_III_sideinfo +{ + unsigned main_data_begin; + unsigned private_bits; + struct + { + struct gr_info_s gr[2]; + } ch[2]; +}; + +int mpeg3audio_III_get_scale_factors_1(mpeg3audio_t *audio, + int *scf, + struct gr_info_s *gr_info, + int ch, + int gr) +{ + static unsigned char slen[2][16] = + {{0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, + {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}}; + int numbits; + int num0 = slen[0][gr_info->scalefac_compress]; + int num1 = slen[1][gr_info->scalefac_compress]; + + if (gr_info->block_type == 2) + { + int i = 18; + numbits = (num0 + num1) * 18; + + if (gr_info->mixed_block_flag) + { + for(i = 8; i; i--) + *scf++ = mpeg3bits_getbits(audio->astream, num0); + i = 9; +/* num0 * 17 + num1 * 18 */ + numbits -= num0; + } + + for( ; i; i--) + *scf++ = mpeg3bits_getbits(audio->astream, num0); + for(i = 18; i; i--) + *scf++ = mpeg3bits_getbits(audio->astream, num1); +/* short[13][0..2] = 0 */ + *scf++ = 0; + *scf++ = 0; + *scf++ = 0; + } + else + { + int i; + int scfsi = gr_info->scfsi; + + if(scfsi < 0) + { +/* scfsi < 0 => granule == 0 */ + for(i = 11; i; i--) + { + *scf++ = mpeg3bits_getbits(audio->astream, num0); + } + for(i = 10; i; i--) + *scf++ = mpeg3bits_getbits(audio->astream, num1); + numbits = (num0 + num1) * 10 + num0; + *scf++ = 0; + } + else + { + numbits = 0; + if(!(scfsi & 0x8)) + { + for(i = 0; i < 6; i++) + { + *scf++ = mpeg3bits_getbits(audio->astream, num0); + } + numbits += num0 * 6; + } + else + { + scf += 6; + } + + if(!(scfsi & 0x4)) + { + for(i = 0; i < 5; i++) + *scf++ = mpeg3bits_getbits(audio->astream, num0); + numbits += num0 * 5; + } + else + { + scf += 5; + } + + if(!(scfsi & 0x2)) + { + for(i = 0; i < 5; i++) + *scf++ = mpeg3bits_getbits(audio->astream, num1); + numbits += num1 * 5; + } + else + { + scf += 5; + } + + if(!(scfsi & 0x1)) + { + for(i = 0; i < 5; i++) + *scf++ = mpeg3bits_getbits(audio->astream, num1); + numbits += num1 * 5; + } + else + { + scf += 5; + } + *scf++ = 0; /* no l[21] in original sources */ + } + } + return numbits; +} + +int mpeg3audio_III_get_scale_factors_2(mpeg3audio_t *audio, + int *scf, + struct gr_info_s *gr_info, + int i_stereo) +{ + unsigned char *pnt; + int i, j, n = 0, numbits = 0; + unsigned int slen; + static unsigned char stab[3][6][4] = + {{{ 6, 5, 5,5 }, { 6, 5, 7,3 }, { 11,10,0,0}, + { 7, 7, 7,0 }, { 6, 6, 6,3 }, { 8, 8,5,0}}, + {{ 9, 9, 9,9 }, { 9, 9,12,6 }, { 18,18,0,0}, + {12,12,12,0 }, {12, 9, 9,6 }, { 15,12,9,0}}, + {{ 6, 9, 9,9 }, { 6, 9,12,6 }, { 15,18,0,0}, + { 6,15,12,0 }, { 6,12, 9,6 }, { 6,18,9,0}}}; + +/* i_stereo AND second channel -> do_layer3() checks this */ + if(i_stereo) + slen = mpeg3_i_slen2[gr_info->scalefac_compress >> 1]; + else + slen = mpeg3_n_slen2[gr_info->scalefac_compress]; + + gr_info->preflag = (slen >> 15) & 0x1; + + n = 0; + if(gr_info->block_type == 2 ) + { + n++; + if(gr_info->mixed_block_flag) + n++; + } + + pnt = stab[n][(slen >> 12) & 0x7]; + + for(i = 0; i < 4; i++) + { + int num = slen & 0x7; + slen >>= 3; + if(num) + { + for(j = 0; j < (int)(pnt[i]); j++) + *scf++ = mpeg3bits_getbits(audio->astream, num); + numbits += pnt[i] * num; + } + else + { + for(j = 0; j < (int)(pnt[i]); j++) + *scf++ = 0; + } + } + + n = (n << 1) + 1; + for(i = 0; i < n; i++) + *scf++ = 0; + + return numbits; +} + +static int pretab1[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0}; +static int pretab2[22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +/* + * Dequantize samples (includes huffman decoding) + * + * 24 is enough because tab13 has max. a 19 bit huffvector + */ + +#define BITSHIFT ((sizeof(long) - 1) * 8) +#define REFRESH_MASK \ + while(num < BITSHIFT) \ + { \ + mask |= mpeg3bits_getbits(audio->astream, 8) << (BITSHIFT - num); \ + num += 8; \ + part2remain -= 8; \ + } + +int mpeg3audio_III_dequantize_sample(mpeg3audio_t *audio, + mpeg3_real_t xr[SBLIMIT][SSLIMIT], + int *scf, + struct gr_info_s *gr_info, + int sfreq, + int part2bits) +{ + int shift = 1 + gr_info->scalefac_scale; + mpeg3_real_t *xrpnt = (mpeg3_real_t*)xr; + int l[3],l3; + int part2remain = gr_info->part2_3_length - part2bits; + int *me; + int num = mpeg3bits_getbitoffset(audio->astream); + long mask = mpeg3bits_getbits(audio->astream, num); +//printf("III_dequantize_sample 1 %08x %d\n", mask, num); + mask = mask << (BITSHIFT + 8 - num); + part2remain -= num; + + { + int bv = gr_info->big_values; + int region1 = gr_info->region1start; + int region2 = gr_info->region2start; + + l3 = ((576 >> 1) - bv) >> 1; + +/* + * we may lose the 'odd' bit here !! + * check this later again + */ + + if(bv <= region1) + { + l[0] = bv; + l[1] = 0; + l[2] = 0; + } + else + { + l[0] = region1; + if(bv <= region2) + { + l[1] = bv - l[0]; l[2] = 0; + } + else + { + l[1] = region2 - l[0]; + l[2] = bv - region2; + } + } + } + + if(gr_info->block_type == 2) + { +/* + * decoding with short or mixed mode BandIndex table + */ + int i, max[4]; + int step = 0, lwin = 3, cb = 0; + register mpeg3_real_t v = 0.0; + register int *m, mc; + + if(gr_info->mixed_block_flag) + { + max[3] = -1; + max[0] = max[1] = max[2] = 2; + m = mpeg3_map[sfreq][0]; + me = mpeg3_mapend[sfreq][0]; + } + else + { + max[0] = max[1] = max[2] = max[3] = -1; +/* max[3] not floatly needed in this case */ + m = mpeg3_map[sfreq][1]; + me = mpeg3_mapend[sfreq][1]; + } + + mc = 0; + for(i = 0; i < 2; i++) + { + int lp = l[i]; + struct newhuff *h = mpeg3_ht + gr_info->table_select[i]; + for( ; lp; lp--, mc--) + { + register int x,y; + if(!mc) + { + mc = *m++; + xrpnt = ((mpeg3_real_t*)xr) + (*m++); + lwin = *m++; + cb = *m++; + if(lwin == 3) + { + v = gr_info->pow2gain[(*scf++) << shift]; + step = 1; + } + else + { + v = gr_info->full_gain[lwin][(*scf++) << shift]; + step = 3; + } + } + + { + register short *val = h->table; + REFRESH_MASK; + while((y = *val++) < 0) + { + if (mask < 0) + val -= y; + num--; + mask <<= 1; + } + x = y >> 4; + y &= 0xf; + } + + if(x == 15 && h->linbits) + { + max[lwin] = cb; + REFRESH_MASK; + x += ((unsigned long)mask) >> (BITSHIFT + 8 - h->linbits); + num -= h->linbits + 1; + mask <<= h->linbits; + if(mask < 0) + *xrpnt = -mpeg3_ispow[x] * v; + else + *xrpnt = mpeg3_ispow[x] * v; + mask <<= 1; + } + else + if(x) + { + max[lwin] = cb; + if(mask < 0) + *xrpnt = -mpeg3_ispow[x] * v; + else + *xrpnt = mpeg3_ispow[x] * v; + num--; + mask <<= 1; + } + else + *xrpnt = 0.0; + + xrpnt += step; + if(y == 15 && h->linbits) + { + max[lwin] = cb; + REFRESH_MASK; + y += ((unsigned long) mask) >> (BITSHIFT + 8 - h->linbits); + num -= h->linbits + 1; + mask <<= h->linbits; + if(mask < 0) + *xrpnt = -mpeg3_ispow[y] * v; + else + *xrpnt = mpeg3_ispow[y] * v; + mask <<= 1; + } + else + if(y) + { + max[lwin] = cb; + if(mask < 0) + *xrpnt = -mpeg3_ispow[y] * v; + else + *xrpnt = mpeg3_ispow[y] * v; + num--; + mask <<= 1; + } + else + *xrpnt = 0.0; + xrpnt += step; + } + } + + for( ;l3 && (part2remain + num > 0); l3--) + { + struct newhuff *h = mpeg3_htc + gr_info->count1table_select; + register short *val = h->table, a; + + REFRESH_MASK; + while((a = *val++) < 0) + { + if (mask < 0) + val -= a; + num--; + mask <<= 1; + } + if(part2remain + num <= 0) + { + num -= part2remain + num; + break; + } + + for(i = 0; i < 4; i++) + { + if(!(i & 1)) + { + if(!mc) + { + mc = *m++; + xrpnt = ((mpeg3_real_t*)xr) + (*m++); + lwin = *m++; + cb = *m++; + if(lwin == 3) + { + v = gr_info->pow2gain[(*scf++) << shift]; + step = 1; + } + else + { + v = gr_info->full_gain[lwin][(*scf++) << shift]; + step = 3; + } + } + mc--; + } + if((a & (0x8 >> i))) + { + max[lwin] = cb; + if(part2remain + num <= 0) + { + break; + } + if(mask < 0) + *xrpnt = -v; + else + *xrpnt = v; + num--; + mask <<= 1; + } + else + *xrpnt = 0.0; + xrpnt += step; + } + } + + if(lwin < 3) + { +/* short band? */ + while(1) + { + for( ;mc > 0; mc--) + { +/* short band -> step=3 */ + *xrpnt = 0.0; + xrpnt += 3; + *xrpnt = 0.0; + xrpnt += 3; + } + if(m >= me) + break; + mc = *m++; + xrpnt = ((mpeg3_real_t*)xr) + *m++; +/* optimize: field will be set to zero at the end of the function */ + if(*m++ == 0) + break; +/* cb */ + m++; + } + } + + gr_info->maxband[0] = max[0] + 1; + gr_info->maxband[1] = max[1] + 1; + gr_info->maxband[2] = max[2] + 1; + gr_info->maxbandl = max[3] + 1; + + { + int rmax = max[0] > max[1] ? max[0] : max[1]; + rmax = (rmax > max[2] ? rmax : max[2]) + 1; + gr_info->maxb = rmax ? mpeg3_shortLimit[sfreq][rmax] : mpeg3_longLimit[sfreq][max[3] + 1]; + } + + } + else + { +/* + * decoding with 'long' BandIndex table (block_type != 2) + */ + int *pretab = gr_info->preflag ? pretab1 : pretab2; + int i, max = -1; + int cb = 0; + int *m = mpeg3_map[sfreq][2]; + register mpeg3_real_t v = 0.0; + int mc = 0; + +/* + * long hash table values + */ + for(i = 0; i < 3; i++) + { + int lp = l[i]; + struct newhuff *h = mpeg3_ht + gr_info->table_select[i]; + + for(; lp; lp--, mc--) + { + int x, y; + + if(!mc) + { + mc = *m++; + cb = *m++; + if(cb == 21) + v = 0.0; + else + v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift]; + } + { + register short *val = h->table; + REFRESH_MASK; + while((y = *val++) < 0) + { + if(mask < 0) + val -= y; + num--; + mask <<= 1; + } + x = y >> 4; + y &= 0xf; + } + + if(x == 15 && h->linbits) + { + max = cb; + REFRESH_MASK; + x += ((unsigned long) mask) >> (BITSHIFT + 8 - h->linbits); + num -= h->linbits + 1; + mask <<= h->linbits; + if(mask < 0) + *xrpnt++ = -mpeg3_ispow[x] * v; + else + *xrpnt++ = mpeg3_ispow[x] * v; + mask <<= 1; + } + else + if(x) + { + max = cb; + if(mask < 0) + *xrpnt++ = -mpeg3_ispow[x] * v; + else + *xrpnt++ = mpeg3_ispow[x] * v; + num--; + mask <<= 1; + } + else + *xrpnt++ = 0.0; + + if(y == 15 && h->linbits) + { + max = cb; + REFRESH_MASK; + y += ((unsigned long) mask) >> (BITSHIFT + 8 - h->linbits); + num -= h->linbits + 1; + mask <<= h->linbits; + if(mask < 0) + *xrpnt++ = -mpeg3_ispow[y] * v; + else + *xrpnt++ = mpeg3_ispow[y] * v; + mask <<= 1; + } + else + if(y) + { + max = cb; + if(mask < 0) + *xrpnt++ = -mpeg3_ispow[y] * v; + else + *xrpnt++ = mpeg3_ispow[y] * v; + num--; + mask <<= 1; + } + else + *xrpnt++ = 0.0; + } + } + +/* + * short (count1table) values + */ + for( ; l3 && (part2remain + num > 0); l3--) + { + struct newhuff *h = mpeg3_htc + gr_info->count1table_select; + register short *val = h->table, a; + + REFRESH_MASK; + while((a = *val++) < 0) + { + if(mask < 0) + val -= a; + num--; + mask <<= 1; + } + if(part2remain + num <= 0) + { + num -= part2remain + num; + break; + } + + for(i = 0; i < 4; i++) + { + if(!(i & 1)) + { + if(!mc) + { + mc = *m++; + cb = *m++; + if(cb == 21) + v = 0.0; + else + v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift]; + } + mc--; + } + if((a & (0x8 >> i))) + { + max = cb; + if(part2remain + num <= 0) + { + break; + } + if(mask < 0) + *xrpnt++ = -v; + else + *xrpnt++ = v; + num--; + mask <<= 1; + } + else + *xrpnt++ = 0.0; + } + } + + gr_info->maxbandl = max + 1; + gr_info->maxb = mpeg3_longLimit[sfreq][gr_info->maxbandl]; + } + + part2remain += num; + +//printf("III_dequantize_sample 2 %d %04x\n", num, mpeg3bits_showbits(audio->astream, 16)); + mpeg3bits_start_reverse(audio->astream); + mpeg3bits_getbits_reverse(audio->astream, num); + mpeg3bits_start_forward(audio->astream); +//printf("III_dequantize_sample 3 %d %04x\n", audio->astream->bit_number, mpeg3bits_showbits(audio->astream, 16)); + num = 0; + + while(xrpnt < &xr[SBLIMIT][0]) + *xrpnt++ = 0.0; + + while(part2remain > 16) + { + mpeg3bits_getbits(audio->astream, 16); /* Dismiss stuffing Bits */ + part2remain -= 16; + } + if(part2remain > 0) + { + mpeg3bits_getbits(audio->astream, part2remain); + } + else + if(part2remain < 0) + { + fprintf(stderr,"mpeg3audio_III_dequantize_sample: Can't rewind stream %d bits!\n", -part2remain); + return 1; /* -> error */ + } + return 0; +} + +int mpeg3audio_III_get_side_info(mpeg3audio_t *audio, + struct mpeg3_III_sideinfo *si, + int channels, + int ms_stereo, + long sfreq, + int single, + int lsf) +{ + int ch, gr; + int powdiff = (single == 3) ? 4 : 0; + static const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } }; + const int *tab = tabs[lsf]; + + si->main_data_begin = mpeg3bits_getbits(audio->astream, tab[1]); + if(channels == 1) + si->private_bits = mpeg3bits_getbits(audio->astream, tab[2]); + else + si->private_bits = mpeg3bits_getbits(audio->astream, tab[3]); + if(!lsf) + { + for(ch = 0; ch < channels; ch++) + { + si->ch[ch].gr[0].scfsi = -1; + si->ch[ch].gr[1].scfsi = mpeg3bits_getbits(audio->astream, 4); + } + } + + for(gr = 0; gr < tab[0]; gr++) + { + for(ch = 0; ch < channels; ch++) + { + register struct gr_info_s *gr_info = &(si->ch[ch].gr[gr]); + + gr_info->part2_3_length = mpeg3bits_getbits(audio->astream, 12); + gr_info->big_values = mpeg3bits_getbits(audio->astream, 9); + if(gr_info->big_values > 288) + { + fprintf(stderr,"mpeg3_III_get_side_info: big_values too large!\n"); + gr_info->big_values = 288; + } + gr_info->pow2gain = mpeg3_gainpow2 + 256 - mpeg3bits_getbits(audio->astream, 8) + powdiff; + if(ms_stereo) + gr_info->pow2gain += 2; + gr_info->scalefac_compress = mpeg3bits_getbits(audio->astream, tab[4]); + + if(mpeg3bits_getbits(audio->astream, 1)) + { +/* window switch flag */ + int i; + gr_info->block_type = mpeg3bits_getbits(audio->astream, 2); + gr_info->mixed_block_flag = mpeg3bits_getbits(audio->astream, 1); + gr_info->table_select[0] = mpeg3bits_getbits(audio->astream, 5); + gr_info->table_select[1] = mpeg3bits_getbits(audio->astream, 5); +/* + * table_select[2] not needed, because there is no region2, + * but to satisfy some verifications tools we set it either. + */ + gr_info->table_select[2] = 0; + for(i = 0; i < 3; i++) + gr_info->full_gain[i] = gr_info->pow2gain + (mpeg3bits_getbits(audio->astream, 3) << 3); + + if(gr_info->block_type == 0) + { + fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n"); + return 1; + } + +/* region_count/start parameters are implicit in this case. */ + if(!lsf || gr_info->block_type == 2) + gr_info->region1start = 36 >> 1; + else + { +/* check this again for 2.5 and sfreq=8 */ + if(sfreq == 8) + gr_info->region1start = 108 >> 1; + else + gr_info->region1start = 54 >> 1; + } + gr_info->region2start = 576 >> 1; + } + else + { + int i, r0c, r1c; + for(i = 0; i < 3; i++) + gr_info->table_select[i] = mpeg3bits_getbits(audio->astream, 5); + + r0c = mpeg3bits_getbits(audio->astream, 4); + r1c = mpeg3bits_getbits(audio->astream, 3); + gr_info->region1start = mpeg3_bandInfo[sfreq].longIdx[r0c + 1] >> 1 ; + gr_info->region2start = mpeg3_bandInfo[sfreq].longIdx[r0c + 1 + r1c + 1] >> 1; + gr_info->block_type = 0; + gr_info->mixed_block_flag = 0; + } + if(!lsf) gr_info->preflag = mpeg3bits_getbits(audio->astream, 1); + gr_info->scalefac_scale = mpeg3bits_getbits(audio->astream, 1); + gr_info->count1table_select = mpeg3bits_getbits(audio->astream, 1); + } + } + return 0; +} + +int mpeg3audio_III_hybrid(mpeg3audio_t *audio, + mpeg3_real_t fsIn[SBLIMIT][SSLIMIT], + mpeg3_real_t tsOut[SSLIMIT][SBLIMIT], + int ch, + struct gr_info_s *gr_info) +{ + mpeg3_real_t *tspnt = (mpeg3_real_t *) tsOut; + mpeg3_real_t *rawout1,*rawout2; + int bt, sb = 0; + + + { + int b = audio->mp3_blc[ch]; + rawout1 = audio->mp3_block[b][ch]; + b = -b + 1; + rawout2 = audio->mp3_block[b][ch]; + audio->mp3_blc[ch] = b; + } + + if(gr_info->mixed_block_flag) + { + sb = 2; + mpeg3audio_dct36(fsIn[0], rawout1, rawout2, mpeg3_win[0], tspnt); + mpeg3audio_dct36(fsIn[1], rawout1 + 18, rawout2 + 18, mpeg3_win1[0], tspnt + 1); + rawout1 += 36; + rawout2 += 36; + tspnt += 2; + } + + bt = gr_info->block_type; + if(bt == 2) + { + for( ; sb < gr_info->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36) + { + mpeg3audio_dct12(fsIn[sb] ,rawout1 ,rawout2 ,mpeg3_win[2] ,tspnt); + mpeg3audio_dct12(fsIn[sb + 1], rawout1 + 18, rawout2 + 18, mpeg3_win1[2], tspnt + 1); + } + } + else + { + for( ; sb < gr_info->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36) + { + mpeg3audio_dct36(fsIn[sb], rawout1, rawout2, mpeg3_win[bt], tspnt); + mpeg3audio_dct36(fsIn[sb + 1], rawout1 + 18, rawout2 + 18, mpeg3_win1[bt], tspnt + 1); + } + } + + for( ; sb < SBLIMIT; sb++, tspnt++) + { + int i; + for(i = 0; i < SSLIMIT; i++) + { + tspnt[i * SBLIMIT] = *rawout1++; + *rawout2++ = 0.0; + } + } + return 0; +} + +int mpeg3audio_III_antialias(mpeg3audio_t *audio, + mpeg3_real_t xr[SBLIMIT][SSLIMIT], + struct gr_info_s *gr_info) +{ + int sblim; + + if(gr_info->block_type == 2) + { + if(!gr_info->mixed_block_flag) + return 0; + sblim = 1; + } + else + { + sblim = gr_info->maxb-1; + } + +/* 31 alias-reduction operations between each pair of sub-bands */ +/* with 8 butterflies between each pair */ + + { + int sb; + mpeg3_real_t *xr1 = (mpeg3_real_t*)xr[1]; + + for(sb = sblim; sb; sb--, xr1 += 10) + { + int ss; + mpeg3_real_t *cs, *ca; + mpeg3_real_t *xr2; + cs = mpeg3_aa_cs; + ca = mpeg3_aa_ca; + xr2 = xr1; + + for(ss = 7; ss >= 0; ss--) + { +/* upper and lower butterfly inputs */ + register mpeg3_real_t bu, bd; + bu = *--xr2; + bd = *xr1; + *xr2 = (bu * (*cs) ) - (bd * (*ca) ); + *xr1++ = (bd * (*cs++) ) + (bu * (*ca++) ); + } + } + } + return 0; +} + +/* + * III_stereo: calculate mpeg3_real_t channel values for Joint-I-Stereo-mode + */ +int mpeg3audio_III_i_stereo(mpeg3audio_t *audio, + mpeg3_real_t xr_buf[2][SBLIMIT][SSLIMIT], + int *scalefac, + struct gr_info_s *gr_info, + int sfreq, + int ms_stereo, + int lsf) +{ + mpeg3_real_t (*xr)[SBLIMIT*SSLIMIT] = (mpeg3_real_t (*)[SBLIMIT*SSLIMIT] ) xr_buf; + struct mpeg3_bandInfoStruct *bi = &mpeg3_bandInfo[sfreq]; + const mpeg3_real_t *tab1, *tab2; + + int tab; +/* TODO: optimize as static */ + static const mpeg3_real_t *tabs[3][2][2] = + { + { { mpeg3_tan1_1, mpeg3_tan2_1 } , { mpeg3_tan1_2, mpeg3_tan2_2 } }, + { { mpeg3_pow1_1[0], mpeg3_pow2_1[0] } , { mpeg3_pow1_2[0], mpeg3_pow2_2[0] } } , + { { mpeg3_pow1_1[1], mpeg3_pow2_1[1] } , { mpeg3_pow1_2[1], mpeg3_pow2_2[1] } } + }; + + tab = lsf + (gr_info->scalefac_compress & lsf); + tab1 = tabs[tab][ms_stereo][0]; + tab2 = tabs[tab][ms_stereo][1]; + + if(gr_info->block_type == 2) + { + int lwin,do_l = 0; + if(gr_info->mixed_block_flag) + do_l = 1; + + for(lwin = 0; lwin < 3; lwin++) + { +/* process each window */ +/* get first band with zero values */ +/* sfb is minimal 3 for mixed mode */ + int is_p, sb, idx, sfb = gr_info->maxband[lwin]; + if(sfb > 3) do_l = 0; + + for( ; sfb < 12 ; sfb++) + { +/* scale: 0-15 */ + is_p = scalefac[sfb * 3 + lwin - gr_info->mixed_block_flag]; + if(is_p != 7) + { + mpeg3_real_t t1, t2; + sb = bi->shortDiff[sfb]; + idx = bi->shortIdx[sfb] + lwin; + t1 = tab1[is_p]; + t2 = tab2[is_p]; + for( ; sb > 0; sb--, idx += 3) + { + mpeg3_real_t v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + } + +/* in the original: copy 10 to 11 , here: copy 11 to 12 +maybe still wrong??? (copy 12 to 13?) */ +/* scale: 0-15 */ + is_p = scalefac[11 * 3 + lwin - gr_info->mixed_block_flag]; + sb = bi->shortDiff[12]; + idx = bi->shortIdx[12] + lwin; + if(is_p != 7) + { + mpeg3_real_t t1, t2; + t1 = tab1[is_p]; + t2 = tab2[is_p]; + for( ; sb > 0; sb--, idx += 3) + { + mpeg3_real_t v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + } /* end for(lwin; .. ; . ) */ + +/* also check l-part, if ALL bands in the three windows are 'empty' +* and mode = mixed_mode +*/ + if(do_l) + { + int sfb = gr_info->maxbandl; + int idx = bi->longIdx[sfb]; + + for ( ; sfb < 8; sfb++) + { + int sb = bi->longDiff[sfb]; +/* scale: 0-15 */ + int is_p = scalefac[sfb]; + if(is_p != 7) + { + mpeg3_real_t t1, t2; + t1 = tab1[is_p]; + t2 = tab2[is_p]; + for( ; sb > 0; sb--, idx++) + { + mpeg3_real_t v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + else + idx += sb; + } + } + } + else + { +/* ((gr_info->block_type != 2)) */ + int sfb = gr_info->maxbandl; + int is_p, idx = bi->longIdx[sfb]; + for( ; sfb < 21; sfb++) + { + int sb = bi->longDiff[sfb]; +/* scale: 0-15 */ + is_p = scalefac[sfb]; + if(is_p != 7) + { + mpeg3_real_t t1, t2; + t1 = tab1[is_p]; + t2 = tab2[is_p]; + for( ; sb > 0; sb--, idx++) + { + mpeg3_real_t v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + else + idx += sb; + } + + is_p = scalefac[20]; + if(is_p != 7) + { +/* copy l-band 20 to l-band 21 */ + int sb; + mpeg3_real_t t1 = tab1[is_p], t2 = tab2[is_p]; + + for(sb = bi->longDiff[21]; sb > 0; sb--, idx++) + { + mpeg3_real_t v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + } /* ... */ +} + +/* Read just the frame after a seek. */ +int mpeg3audio_read_layer3_frame(mpeg3audio_t *audio) +{ + int result = 0; + + result = mpeg3audio_read_header(audio); + if(!result) + { + audio->bsbufold = audio->bsbuf; + audio->bsbuf = audio->bsspace[audio->bsnum] + 512; + audio->bsnum ^= 1; + result = mpeg3bits_read_buffer(audio->astream, audio->bsbuf, audio->framesize); + } + + return result; +} + +int mpeg3audio_dolayer3(mpeg3audio_t *audio) +{ + int gr, ch, ss; + int scalefacs[2][39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */ + struct mpeg3_III_sideinfo sideinfo; + int channels = audio->channels; + int single = audio->single; + int ms_stereo, i_stereo; + int sfreq = audio->sampling_frequency_code; + int stereo1, granules; + int i; + +/* flip/init buffer */ + audio->bsbufold = audio->bsbuf; + audio->bsbuf = audio->bsspace[audio->bsnum] + 512; + audio->bsnum ^= 1; + +/* read main data into memory */ + if(mpeg3bits_read_buffer(audio->astream, audio->bsbuf, audio->framesize)) + return 1; + mpeg3bits_use_ptr(audio->astream, audio->bsbuf); + +/* CRC must be skipped here for proper alignment with the backstep */ + if(audio->error_protection) + mpeg3bits_getbits(audio->astream, 16); + + if(channels == 1) + { +/* stream is mono */ + stereo1 = 1; + single = 0; + } + else + { +/* Stereo */ + stereo1 = 2; + } + + if(audio->mode == MPG_MD_JOINT_STEREO) + { + ms_stereo = (audio->mode_ext & 0x2) >> 1; + i_stereo = audio->mode_ext & 0x1; + } + else + ms_stereo = i_stereo = 0; + + if(audio->lsf) + { + granules = 1; + } + else + { + granules = 2; + } + + if(mpeg3audio_III_get_side_info(audio, &sideinfo, channels, ms_stereo, sfreq, single, audio->lsf)) + return 1; + +/* Step back */ + if(sideinfo.main_data_begin >= 512) + return 1; + + if(sideinfo.main_data_begin) + { + memcpy(audio->bsbuf + audio->ssize - sideinfo.main_data_begin, + audio->bsbufold + audio->prev_framesize - sideinfo.main_data_begin, + sideinfo.main_data_begin); + mpeg3bits_use_ptr(audio->astream, audio->bsbuf + audio->ssize - sideinfo.main_data_begin); + } + + for(gr = 0; gr < granules; gr++) + { + mpeg3_real_t hybridIn [2][SBLIMIT][SSLIMIT]; + mpeg3_real_t hybridOut[2][SSLIMIT][SBLIMIT]; + + { + struct gr_info_s *gr_info = &(sideinfo.ch[0].gr[gr]); + long part2bits; + if(audio->lsf) + part2bits = mpeg3audio_III_get_scale_factors_2(audio, scalefacs[0], gr_info, 0); + else + part2bits = mpeg3audio_III_get_scale_factors_1(audio, scalefacs[0], gr_info, 0, gr); +//printf("dolayer3 4 %04x\n", mpeg3bits_showbits(audio->astream, 16)); + + if(mpeg3audio_III_dequantize_sample(audio, hybridIn[0], scalefacs[0], gr_info, sfreq, part2bits)) + { + mpeg3bits_use_demuxer(audio->astream); + return 1; + } +//printf("dolayer3 5 %04x\n", mpeg3bits_showbits(audio->astream, 16)); + } + + if(channels == 2) + { + struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]); + long part2bits; + if(audio->lsf) + part2bits = mpeg3audio_III_get_scale_factors_2(audio, scalefacs[1], gr_info, i_stereo); + else + part2bits = mpeg3audio_III_get_scale_factors_1(audio, scalefacs[1], gr_info, 1, gr); + + if(mpeg3audio_III_dequantize_sample(audio, hybridIn[1], scalefacs[1], gr_info, sfreq, part2bits)) + { + mpeg3bits_use_demuxer(audio->astream); + return 1; + } + + if(ms_stereo) + { + int i; + int maxb = sideinfo.ch[0].gr[gr].maxb; + if(sideinfo.ch[1].gr[gr].maxb > maxb) + maxb = sideinfo.ch[1].gr[gr].maxb; + for(i = 0; i < SSLIMIT * maxb; i++) + { + mpeg3_real_t tmp0 = ((mpeg3_real_t*)hybridIn[0])[i]; + mpeg3_real_t tmp1 = ((mpeg3_real_t*)hybridIn[1])[i]; + ((mpeg3_real_t*)hybridIn[0])[i] = tmp0 + tmp1; + ((mpeg3_real_t*)hybridIn[1])[i] = tmp0 - tmp1; + } + } + + if(i_stereo) + mpeg3audio_III_i_stereo(audio, hybridIn, scalefacs[1], gr_info, sfreq, ms_stereo, audio->lsf); + + if(ms_stereo || i_stereo || (single == 3)) + { + if(gr_info->maxb > sideinfo.ch[0].gr[gr].maxb) + sideinfo.ch[0].gr[gr].maxb = gr_info->maxb; + else + gr_info->maxb = sideinfo.ch[0].gr[gr].maxb; + } + + switch(single) + { + case 3: + { + register int i; + register mpeg3_real_t *in0 = (mpeg3_real_t*)hybridIn[0], *in1 = (mpeg3_real_t*)hybridIn[1]; +/* *0.5 done by pow-scale */ + for(i = 0; i < SSLIMIT * gr_info->maxb; i++, in0++) + *in0 = (*in0 + *in1++); + } + break; + case 1: + { + register int i; + register mpeg3_real_t *in0 = (mpeg3_real_t*)hybridIn[0], *in1 = (mpeg3_real_t*)hybridIn[1]; + for(i = 0; i < SSLIMIT * gr_info->maxb; i++) + *in0++ = *in1++; + } + break; + } + } + + for(ch = 0; ch < stereo1; ch++) + { + struct gr_info_s *gr_info = &(sideinfo.ch[ch].gr[gr]); + mpeg3audio_III_antialias(audio, hybridIn[ch], gr_info); + mpeg3audio_III_hybrid(audio, hybridIn[ch], hybridOut[ch], ch, gr_info); + } + + for(ss = 0; ss < SSLIMIT; ss++) + { + if(single >= 0) + { + mpeg3audio_synth_mono(audio, hybridOut[0][ss], audio->pcm_sample, &(audio->pcm_point)); + } + else + { + int p1 = audio->pcm_point; + mpeg3audio_synth_stereo(audio, hybridOut[0][ss], 0, audio->pcm_sample, &p1); + mpeg3audio_synth_stereo(audio, hybridOut[1][ss], 1, audio->pcm_sample, &(audio->pcm_point)); + } + + if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels) + { +/* Need more room */ + mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels); + } + } + } + + mpeg3bits_use_demuxer(audio->astream); + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/mantissa.c b/core/multimedia/opieplayer/libmpeg3/audio/mantissa.c new file mode 100644 index 0000000..05fe251 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/mantissa.c @@ -0,0 +1,387 @@ +/* + * + * mantissa.c Copyright (C) Aaron Holtzman - May 1999 + * + * + * This file is part of libmpeg3 + * + * libmpeg3 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * libmpeg3 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" + + +/* Lookup tables of 0.16 two's complement quantization values */ +static short mpeg3_q_1[3] = +{ + (-2 << 15) / 3, + 0, + (2 << 15) / 3 +}; + +static short mpeg3_q_2[5] = +{ + (-4 << 15) / 5, + ((-2 << 15) / 5) << 1, + 0, + (2 << 15) / 5, + ((4 << 15) / 5) << 1 +}; + +static short mpeg3_q_3[7] = +{ + (-6 << 15) / 7, + (-4 << 15) / 7, + (-2 << 15) / 7, + 0, + (2 << 15) / 7, + (4 << 15) / 7, + (6 << 15) / 7 +}; + +static short mpeg3_q_4[11] = +{ + (-10 << 15) / 11, + (-8 << 15) / 11, + (-6 << 15) / 11, + (-4 << 15) / 11, + (-2 << 15) / 11, + 0, + ( 2 << 15) / 11, + ( 4 << 15) / 11, + ( 6 << 15) / 11, + ( 8 << 15) / 11, + (10 << 15) / 11 +}; + +static short mpeg3_q_5[15] = +{ + (-14 << 15) / 15, + (-12 << 15) / 15, + (-10 << 15) / 15, + (-8 << 15) / 15, + (-6 << 15) / 15, + (-4 << 15) / 15, + (-2 << 15) / 15, + 0, + ( 2 << 15) / 15, + ( 4 << 15) / 15, + ( 6 << 15) / 15, + ( 8 << 15) / 15, + (10 << 15) / 15, + (12 << 15) / 15, + (14 << 15) / 15 +}; + +static short mpeg3_qnttztab[16] = {0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16}; + + +/* */ +/* Scale factors for tofloat */ +/* */ + +static const unsigned MPEG3_INT32 mpeg3_scale_factors[25] = +{ + 0x38000000, /*2 ^ -(0 + 15) */ + 0x37800000, /*2 ^ -(1 + 15) */ + 0x37000000, /*2 ^ -(2 + 15) */ + 0x36800000, /*2 ^ -(3 + 15) */ + 0x36000000, /*2 ^ -(4 + 15) */ + 0x35800000, /*2 ^ -(5 + 15) */ + 0x35000000, /*2 ^ -(6 + 15) */ + 0x34800000, /*2 ^ -(7 + 15) */ + 0x34000000, /*2 ^ -(8 + 15) */ + 0x33800000, /*2 ^ -(9 + 15) */ + 0x33000000, /*2 ^ -(10 + 15) */ + 0x32800000, /*2 ^ -(11 + 15) */ + 0x32000000, /*2 ^ -(12 + 15) */ + 0x31800000, /*2 ^ -(13 + 15) */ + 0x31000000, /*2 ^ -(14 + 15) */ + 0x30800000, /*2 ^ -(15 + 15) */ + 0x30000000, /*2 ^ -(16 + 15) */ + 0x2f800000, /*2 ^ -(17 + 15) */ + 0x2f000000, /*2 ^ -(18 + 15) */ + 0x2e800000, /*2 ^ -(19 + 15) */ + 0x2e000000, /*2 ^ -(20 + 15) */ + 0x2d800000, /*2 ^ -(21 + 15) */ + 0x2d000000, /*2 ^ -(22 + 15) */ + 0x2c800000, /*2 ^ -(23 + 15) */ + 0x2c000000 /*2 ^ -(24 + 15) */ +}; + +static MPEG3_FLOAT32 *mpeg3_scale_factor = (MPEG3_FLOAT32*)mpeg3_scale_factors; + +static inline mpeg3_real_t mpeg3audio_ac3_tofloat(unsigned short exponent, int mantissa) +{ + mpeg3_real_t x; + x = mantissa * mpeg3_scale_factor[exponent]; + return x; +} + +static inline void mpeg3audio_ac3_mantissa_reset(mpeg3_ac3_mantissa_t *mantissa) +{ + mantissa->m_1[2] = mantissa->m_1[1] = mantissa->m_1[0] = 0; + mantissa->m_2[2] = mantissa->m_2[1] = mantissa->m_2[0] = 0; + mantissa->m_4[1] = mantissa->m_4[0] = 0; +/* Force new groups to be loaded */ + mantissa->m_1_pointer = mantissa->m_2_pointer = mantissa->m_4_pointer = 3; +} + +/* + * Generate eight bits of pseudo-entropy using a 16 bit linear + * feedback shift register (LFSR). The primitive polynomial used + * is 1 + x^4 + x^14 + x^16. + * + * The distribution is uniform, over the range [-0.707,0.707] + * + */ +inline unsigned int mpeg3audio_ac3_dither_gen(mpeg3audio_t *audio) +{ + int i; + unsigned int state; + +/* explicitly bring the state into a local var as gcc > 3.0? */ +/* doesn't know how to optimize out the stores */ + state = audio->ac3_lfsr_state; + +/* Generate eight pseudo random bits */ + for(i = 0; i < 8; i++) + { + state <<= 1; + + if(state & 0x10000) + state ^= 0xa011; + } + + audio->ac3_lfsr_state = state; + return (((((int)state << 8) >> 8) * (int)(0.707106f * 256.0f)) >> 16); +} + + +/* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */ +static inline unsigned short mpeg3audio_ac3_mantissa_get(mpeg3audio_t *audio, + unsigned short bap, + unsigned short dithflag) +{ + unsigned short mantissa; + unsigned int group_code; + mpeg3_ac3_mantissa_t *mantissa_struct = &(audio->ac3_mantissa); + +/* If the bap is 0-5 then we have special cases to take care of */ + switch(bap) + { + case 0: + if(dithflag) + mantissa = mpeg3audio_ac3_dither_gen(audio); + else + mantissa = 0; + break; + + case 1: + if(mantissa_struct->m_1_pointer > 2) + { + group_code = mpeg3bits_getbits(audio->astream, 5); + + if(group_code > 26) + { +/* FIXME do proper block error handling */ + fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 1 %d\n", group_code); + return 0; + } + + mantissa_struct->m_1[0] = group_code / 9; + mantissa_struct->m_1[1] = (group_code % 9) / 3; + mantissa_struct->m_1[2] = (group_code % 9) % 3; + mantissa_struct->m_1_pointer = 0; + } + mantissa = mantissa_struct->m_1[mantissa_struct->m_1_pointer++]; + mantissa = mpeg3_q_1[mantissa]; + break; + + case 2: + if(mantissa_struct->m_2_pointer > 2) + { + group_code = mpeg3bits_getbits(audio->astream, 7); + + if(group_code > 124) + { + fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 2 %d\n", group_code); + return 0; + } + + mantissa_struct->m_2[0] = group_code / 25; + mantissa_struct->m_2[1] = (group_code % 25) / 5; + mantissa_struct->m_2[2] = (group_code % 25) % 5; + mantissa_struct->m_2_pointer = 0; + } + mantissa = mantissa_struct->m_2[mantissa_struct->m_2_pointer++]; + mantissa = mpeg3_q_2[mantissa]; + break; + + case 3: + mantissa = mpeg3bits_getbits(audio->astream, 3); + + if(mantissa > 6) + { + fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 3 %d\n", mantissa); + return 0; + } + + mantissa = mpeg3_q_3[mantissa]; + break; + + case 4: + if(mantissa_struct->m_4_pointer > 1) + { + group_code = mpeg3bits_getbits(audio->astream, 7); + + if(group_code > 120) + { + fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 4 %d\n", group_code); + return 0; + } + + mantissa_struct->m_4[0] = group_code / 11; + mantissa_struct->m_4[1] = group_code % 11; + mantissa_struct->m_4_pointer = 0; + } + mantissa = mantissa_struct->m_4[mantissa_struct->m_4_pointer++]; + mantissa = mpeg3_q_4[mantissa]; + break; + + case 5: + mantissa = mpeg3bits_getbits(audio->astream, 4); + + if(mantissa > 14) + { +/* FIXME do proper block error handling */ + fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 5 %d\n", mantissa); + return 0; + } + + mantissa = mpeg3_q_5[mantissa]; + break; + + default: + mantissa = mpeg3bits_getbits(audio->astream, mpeg3_qnttztab[bap]); + mantissa <<= 16 - mpeg3_qnttztab[bap]; + } + return mantissa; +} + +void mpeg3audio_ac3_uncouple_channel(mpeg3audio_t *audio, + mpeg3_real_t samples[], + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk, + unsigned int ch) +{ + unsigned int bnd = 0; + unsigned int sub_bnd = 0; + unsigned int i, j; + MPEG3_FLOAT32 cpl_coord = 1.0; + unsigned int cpl_exp_tmp; + unsigned int cpl_mant_tmp; + short mantissa; + + for(i = audblk->cplstrtmant; i < audblk->cplendmant; ) + { + if(!audblk->cplbndstrc[sub_bnd++]) + { + cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch]; + if(audblk->cplcoexp[ch][bnd] == 15) + cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11; + else + cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10; + + cpl_coord = mpeg3audio_ac3_tofloat(cpl_exp_tmp, cpl_mant_tmp) * 8.0f; + +/*Invert the phase for the right channel if necessary */ + if(bsi->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd]) + cpl_coord *= -1; + + bnd++; + } + + for(j = 0; j < 12; j++) + { +/* Get new dither values for each channel if necessary, so */ +/* the channels are uncorrelated */ + if(audblk->dithflag[ch] && audblk->cpl_bap[i] == 0) + mantissa = mpeg3audio_ac3_dither_gen(audio); + else + mantissa = audblk->cplmant[i]; + + samples[i] = cpl_coord * mpeg3audio_ac3_tofloat(audblk->cpl_exp[i], mantissa);; + + i++; + } + } + return; +} + +int mpeg3audio_ac3_coeff_unpack(mpeg3audio_t *audio, + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk, + mpeg3ac3_stream_samples_t samples) +{ + int i, j; + int done_cpl = 0; + short mantissa; + + mpeg3audio_ac3_mantissa_reset(&(audio->ac3_mantissa)); + + for(i = 0; i < bsi->nfchans && !mpeg3bits_error(audio->astream); i++) + { + for(j = 0; j < audblk->endmant[i] && !mpeg3bits_error(audio->astream); j++) + { + mantissa = mpeg3audio_ac3_mantissa_get(audio, audblk->fbw_bap[i][j], audblk->dithflag[i]); + samples[i][j] = mpeg3audio_ac3_tofloat(audblk->fbw_exp[i][j], mantissa); + } + + if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl) && !mpeg3bits_error(audio->astream)) + { +/* ncplmant is equal to 12 * ncplsubnd */ +/* Don't dither coupling channel until channel separation so that + * interchannel noise is uncorrelated */ + for(j = audblk->cplstrtmant; + j < audblk->cplendmant && !mpeg3bits_error(audio->astream); + j++) + { + audblk->cplmant[j] = mpeg3audio_ac3_mantissa_get(audio, audblk->cpl_bap[j], 0); + } + done_cpl = 1; + } + } + +/* Uncouple the channel */ + if(audblk->cplinu) + { + if(audblk->chincpl[i]) + mpeg3audio_ac3_uncouple_channel(audio, samples[i], bsi, audblk, i); + } + + if(bsi->lfeon && !mpeg3bits_error(audio->astream)) + { +/* There are always 7 mantissas for lfe, no dither for lfe */ + for(j = 0; j < 7 && !mpeg3bits_error(audio->astream); j++) + mantissa = mpeg3audio_ac3_mantissa_get(audio, audblk->lfe_bap[j], 0); + samples[5][j] = mpeg3audio_ac3_tofloat(audblk->lfe_exp[j], mantissa); + } + + return mpeg3bits_error(audio->astream); +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.c b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.c new file mode 100644 index 0000000..e2d3912 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.c @@ -0,0 +1,536 @@ +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "mpeg3audio.h" +#include "tables.h" + +#include +#include + +mpeg3audio_t* mpeg3audio_allocate_struct(mpeg3_t *file, mpeg3_atrack_t *track) +{ + mpeg3audio_t *audio = (mpeg3audio_t*)calloc(1, sizeof(mpeg3audio_t)); + audio->file = file; + audio->track = track; + audio->astream = mpeg3bits_new_stream(file, track->demuxer); + audio->outscale = 1; + audio->bsbuf = audio->bsspace[1]; + audio->init = 1; + audio->bo = 1; + audio->channels = 1; + return audio; +} + + +int mpeg3audio_delete_struct(mpeg3audio_t *audio) +{ + mpeg3bits_delete_stream(audio->astream); + if(audio->pcm_sample) free(audio->pcm_sample); + free(audio); + return 0; +} + +int mpeg3audio_replace_buffer(mpeg3audio_t *audio, long new_allocation) +{ + long i; + + audio->pcm_sample = (mpeg3_real_t*)realloc( audio->pcm_sample, sizeof(mpeg3_real_t) * new_allocation * audio->channels ); + audio->pcm_allocated = new_allocation; +/* + // Isn't this exactly the same as what the ANSI C function call realloc does, + // or did I miss C Programming 101 ? + + if(!audio->pcm_sample) + { + audio->pcm_sample = (mpeg3_real_t*)malloc(sizeof(mpeg3_real_t) * new_allocation * audio->channels); + audio->pcm_allocated = new_allocation; + } + else + { + mpeg3_real_t *new_samples = (mpeg3_real_t*)malloc(sizeof(mpeg3_real_t) * new_allocation * audio->channels); + for(i = 0; i < audio->pcm_allocated * audio->channels; i++) + { + new_samples[i] = audio->pcm_sample[i]; + } + free(audio->pcm_sample); + audio->pcm_sample = new_samples; + audio->pcm_allocated = new_allocation; + } +*/ + return 0; +} + +int mpeg3audio_read_frame(mpeg3audio_t *audio) +{ + int result = 0; + result = mpeg3audio_read_header(audio); + + if(!result) + { + switch(audio->format) + { + case AUDIO_AC3: + result = mpeg3audio_do_ac3(audio); + break; + + case AUDIO_MPEG: + switch(audio->layer) + { + case 1: + break; + + case 2: + result = mpeg3audio_dolayer2(audio); + break; + + case 3: + result = mpeg3audio_dolayer3(audio); + break; + + default: + result = 1; + break; + } + break; + + case AUDIO_PCM: + result = mpeg3audio_do_pcm(audio); + break; + } + } + + if(!result) + { +/* Byte align the stream */ + mpeg3bits_byte_align(audio->astream); + } + return result; +} + +/* Get the length but also initialize the frame sizes. */ +int mpeg3audio_get_length(mpeg3audio_t *audio, mpeg3_atrack_t *track) +{ + long result = 0; + long framesize1 = 0, total1 = 0; + long framesize2 = 0, total2 = 0; + long total_framesize = 0, total_frames = 0; + long byte_limit = 131072; /* Total bytes to gather information from */ + long total_bytes = 0; + long major_framesize; /* Bigger framesize + header */ + long minor_framesize; /* Smaller framesize + header */ + long major_total; + long minor_total; + mpeg3_t *file = audio->file; + +/* Get the frame sizes */ + mpeg3bits_seek_start(audio->astream); + audio->pcm_point = 0; + result = mpeg3audio_read_frame(audio); /* Stores the framesize */ + audio->samples_per_frame = audio->pcm_point / audio->channels; + + switch(audio->format) + { + case AUDIO_AC3: + audio->avg_framesize = audio->framesize; + break; + + case AUDIO_MPEG: + framesize1 = audio->framesize; + total_bytes += audio->framesize; + total1 = 1; + + while(!result && total_bytes < byte_limit) + { + audio->pcm_point = 0; + result = mpeg3audio_read_frame(audio); + total_bytes += audio->framesize; + if(audio->framesize != framesize1) + { + framesize2 = audio->framesize; + total2 = 1; + break; + } + else + { + total1++; + } + } + + while(!result && total_bytes < byte_limit) + { + audio->pcm_point = 0; + result = mpeg3audio_read_frame(audio); + total_bytes += audio->framesize; + if(audio->framesize != framesize2) + { + break; + } + else + { + total2++; + } + } + + audio->pcm_point = 0; + result = mpeg3audio_read_frame(audio); + if(audio->framesize != framesize1 && audio->framesize != framesize2) + { +/* Variable bit rate. Get the average frame size. */ + while(!result && total_bytes < byte_limit) + { + audio->pcm_point = 0; + result = mpeg3audio_read_frame(audio); + total_bytes += audio->framesize; + if(!result) + { + total_framesize += audio->framesize; + total_frames++; + } + } + audio->avg_framesize = 4 + (total_framesize + framesize1 + framesize2) / (total_frames + total1 + total2); + } + else + { + major_framesize = framesize2 > framesize1 ? framesize2 : framesize1; + major_total = framesize2 > framesize1 ? total2 : total1; + minor_framesize = framesize2 > framesize1 ? framesize1 : framesize2; + minor_total = framesize2 > framesize1 ? total1 : total2; +/* Add the headers to the framesizes */ + audio->avg_framesize = 4 + (major_framesize * major_total + minor_framesize * minor_total) / (major_total + minor_total); + } + break; + + case AUDIO_PCM: + break; + } + +/* Estimate the total samples */ + if(file->is_audio_stream) + { +/* From the raw file */ + result = (long)((float)mpeg3demuxer_total_bytes(audio->astream->demuxer) / audio->avg_framesize * audio->samples_per_frame); + } + else + { +/* Gross approximation from a multiplexed file. */ + result = (long)(mpeg3demux_length(audio->astream->demuxer) * track->sample_rate); +/* result = (long)((mpeg3_real_t)mpeg3_video_frames(file, 0) / mpeg3_frame_rate(file, 0) * track->sample_rate); */ +/* We would scan the multiplexed packets here for the right timecode if only */ +/* they had meaningful timecode. */ + } + + audio->pcm_point = 0; + mpeg3bits_seek_start(audio->astream); + mpeg3audio_reset_synths(audio); + return result; +} + +int mpeg3audio_seek(mpeg3audio_t *audio, long position) +{ + int result = 0; + mpeg3_t *file = audio->file; + mpeg3_atrack_t *track = audio->track; + long frame_number; + long byte_position; + double time_position; + +/* Sample seek wasn't requested */ + if(audio->sample_seek < 0) + { + audio->pcm_position = position; + audio->pcm_size = 0; + return 0; + } + +/* Can't slide buffer. Seek instead. */ + if(!file->is_audio_stream) + { +/* Seek in a multiplexed stream using the multiplexer. */ + time_position = (double)position / track->sample_rate; + result |= mpeg3bits_seek_time(audio->astream, time_position); + audio->pcm_position = (long)mpeg3bits_packet_time(audio->astream) * track->sample_rate; +/*printf("wanted %f got %f\n", time_position, mpeg3bits_packet_time(audio->astream)); */ + } + else + { +/* Seek in an elemental stream. This algorithm achieves sample accuracy on fixed bitrates. */ +/* Forget about variable bitrates or program streams. */ + frame_number = position / audio->samples_per_frame; + byte_position = (long)(audio->avg_framesize * frame_number); + audio->pcm_position = frame_number * audio->samples_per_frame; + + if(byte_position < audio->avg_framesize * 2) + { + result |= mpeg3bits_seek_start(audio->astream); + audio->pcm_position = 0; + } + else + { + result |= mpeg3bits_seek_byte(audio->astream, byte_position); + } + } + +/* Arm the backstep buffer for layer 3 if not at the beginning already. */ + if(byte_position >= audio->avg_framesize * 2 && audio->layer == 3 && !result) + { + result |= mpeg3audio_prev_header(audio); + result |= mpeg3audio_read_layer3_frame(audio); + } + +/* Reset the tables. */ + mpeg3audio_reset_synths(audio); + audio->pcm_size = 0; + audio->pcm_point = 0; + return result; +} + +/* ================================================================ */ +/* ENTRY POINTS */ +/* ================================================================ */ + + + + +mpeg3audio_t* mpeg3audio_new(mpeg3_t *file, mpeg3_atrack_t *track, int format) +{ + mpeg3audio_t *audio = mpeg3audio_allocate_struct(file, track); + int result = 0; + +/* Init tables */ + mpeg3audio_new_decode_tables(audio); + audio->percentage_seek = -1; + audio->sample_seek = -1; + audio->format = format; + +/* Determine the format of the stream */ + if(format == AUDIO_UNKNOWN) + { + if(((mpeg3bits_showbits(audio->astream, 32) & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) + audio->format = AUDIO_AC3; + else + audio->format = AUDIO_MPEG; + } + +/* get channel count */ + result = mpeg3audio_read_header(audio); + +/* Set up the sample buffer */ + mpeg3audio_replace_buffer(audio, 262144); + +/* Copy information to the mpeg struct */ + if(!result) + { + track->channels = audio->channels; + + switch(audio->format) + { + case AUDIO_AC3: + track->sample_rate = mpeg3_ac3_samplerates[audio->sampling_frequency_code]; + break; + + case AUDIO_MPEG: + track->sample_rate = mpeg3_freqs[audio->sampling_frequency_code]; + break; + + case AUDIO_PCM: + track->sample_rate = 48000; + break; + } + + track->total_samples = mpeg3audio_get_length(audio, track); + result |= mpeg3bits_seek_start(audio->astream); + } + else + { + mpeg3audio_delete_struct(audio); + audio = 0; + } + + return audio; +} + +int mpeg3audio_delete(mpeg3audio_t *audio) +{ + mpeg3audio_delete_struct(audio); + return 0; +} + +int mpeg3audio_seek_percentage(mpeg3audio_t *audio, double percentage) +{ + audio->percentage_seek = percentage; + return 0; +} + +int mpeg3audio_seek_sample(mpeg3audio_t *audio, long sample) +{ + audio->sample_seek = sample; + return 0; +} + +/* Read raw frames for concatenation purposes */ +int mpeg3audio_read_raw(mpeg3audio_t *audio, unsigned char *output, long *size, long max_size) +{ + int result = 0; + int i; + *size = 0; + + switch(audio->format) + { + case AUDIO_AC3: +/* Just write the AC3 stream */ + if(mpeg3bits_read_buffer(audio->astream, output, audio->framesize)) + return 1; + *size = audio->framesize; + break; + + case AUDIO_MPEG: +/* Fix the mpeg stream */ + result = mpeg3audio_read_header(audio); + if(!result) + { + if(max_size < 4) return 1; + *output++ = (audio->newhead & 0xff000000) >> 24; + *output++ = (audio->newhead & 0xff0000) >> 16; + *output++ = (audio->newhead & 0xff00) >> 8; + *output++ = (audio->newhead & 0xff); + *size += 4; + + if(max_size < 4 + audio->framesize) return 1; + if(mpeg3bits_read_buffer(audio->astream, output, audio->framesize)) + return 1; + + *size += audio->framesize; + } + break; + + case AUDIO_PCM: + if(mpeg3bits_read_buffer(audio->astream, output, audio->framesize)) + return 1; + *size = audio->framesize; + break; + } + return result; +} + +/* Channel is 0 to channels - 1 */ +int mpeg3audio_decode_audio(mpeg3audio_t *audio, + mpeg3_real_t *output_f, + short *output_i, int sampleSpacing, + int channel, + long start_position, + long len) +{ + long allocation_needed = len + MPEG3AUDIO_PADDING; + long i, j, result = 0; + mpeg3_t *file = audio->file; + mpeg3_atrack_t *atrack = audio->track; + long attempts; + +/* Create new buffer */ + if(audio->pcm_allocated < allocation_needed) + { + mpeg3audio_replace_buffer(audio, allocation_needed); + } + +/* There was a percentage seek */ + if(audio->percentage_seek >= 0) + { + mpeg3bits_seek_percentage(audio->astream, audio->percentage_seek); +/* Force the pcm buffer to be reread. */ + audio->pcm_position = start_position; + audio->pcm_size = 0; + audio->percentage_seek = -1; + } + else + { +/* Entire output is in buffer so don't do anything. */ + if(start_position >= audio->pcm_position && start_position < audio->pcm_position + audio->pcm_size && + start_position + len <= audio->pcm_size) + { + ; + } + else +/* Output starts in buffer but ends later so slide it back. */ + if(start_position <= audio->pcm_position + audio->pcm_size && + start_position >= audio->pcm_position) + { + for(i = 0, j = (start_position - audio->pcm_position) * audio->channels; + j < audio->pcm_size * audio->channels; + i++, j++) + { + audio->pcm_sample[i] = audio->pcm_sample[j]; + } + + audio->pcm_point = i; + audio->pcm_size -= start_position - audio->pcm_position; + audio->pcm_position = start_position; + } + else + { +/* Output is outside buffer completely. */ + result = mpeg3audio_seek(audio, start_position); + audio->sample_seek = -1; +/* Check sanity */ + if(start_position < audio->pcm_position) audio->pcm_position = start_position; + } + audio->sample_seek = -1; + } + +/* Read packets until the buffer is full. */ + if(!result) + { + attempts = 0; + result = 1; + while(attempts < 6 && + !mpeg3bits_eof(audio->astream) && + audio->pcm_size + audio->pcm_position < start_position + len) + { + result = mpeg3audio_read_frame(audio); + if(result) attempts++; + audio->pcm_size = audio->pcm_point / audio->channels; + } + } + + + +/* Copy the buffer to the output */ + if(output_f) + { + for(i = 0, j = (start_position - audio->pcm_position) * audio->channels + channel; + i < len && j < audio->pcm_size * audio->channels; + i++, j += audio->channels) + { + output_f[i] = audio->pcm_sample[j]; + } + for( ; i < len; i++) + { + output_f[i] = 0; + } + } + else + if(output_i) + { + int sample; + for(i = 0, j = (start_position - audio->pcm_position) * audio->channels + channel; + i < (len*(sampleSpacing+1)) && j < audio->pcm_size * audio->channels; + i++, j += audio->channels) + { + sample = (int)(audio->pcm_sample[j] * 32767); + if(sample > 32767) sample = 32767; + else + if(sample < -32768) sample = -32768; + + output_i[i] = sample; + i += sampleSpacing; + } + for( ; i < (len*(sampleSpacing+1)); i++) + { + output_i[i] = 0; + i += sampleSpacing; + } + } + + if(audio->pcm_point > 0) + return 0; + else + return result; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.h b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.h new file mode 100644 index 0000000..2117be7 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.h @@ -0,0 +1,144 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3AUDIO_H +#define MPEG3AUDIO_H + +#include "ac3.h" +#include "../bitstream.h" +typedef struct mpeg3_atrack_rec mpeg3_atrack_t; + +#define MAXFRAMESIZE 1792 +#define HDRCMPMASK 0xfffffd00 +#define SBLIMIT 32 +#define SSLIMIT 18 +#define SCALE_BLOCK 12 +#define MPEG3AUDIO_PADDING 1024 + +/* Values for mode */ +#define MPG_MD_STEREO 0 +#define MPG_MD_JOINT_STEREO 1 +#define MPG_MD_DUAL_CHANNEL 2 +#define MPG_MD_MONO 3 + +/* IMDCT variables */ +typedef struct +{ + mpeg3_real_t real; + mpeg3_real_t imag; +} mpeg3_complex_t; + +#define AC3_N 512 + +struct al_table +{ + short bits; + short d; +}; + +typedef struct +{ + struct mpeg3_rec* file; + mpeg3_atrack_t* track; + mpeg3_bits_t *astream; + +/* In order of importance */ + int format; /* format of audio */ + int layer; /* layer if mpeg */ + int channels; + long outscale; + long framenum; + long prev_framesize; + long framesize; /* For mp3 current framesize without header. For AC3 current framesize with header. */ + int avg_framesize; /* Includes the 4 byte header */ + mpeg3_real_t *pcm_sample; /* Interlaced output from synthesizer in floats */ + int pcm_point; /* Float offset in pcm_sample to write to */ + long pcm_position; /* Sample start of pcm_samples in file */ + long pcm_size; /* Number of pcm samples in the buffer */ + long pcm_allocated; /* Allocated number of samples in pcm_samples */ + int sample_seek; + double percentage_seek; + unsigned long oldhead; + unsigned long newhead; + unsigned long firsthead; + int bsnum; + int lsf; + int mpeg35; + int sampling_frequency_code; + int bitrate_index; + int bitrate; + int samples_per_frame; + int padding; + int extension; + int mode; + int mode_ext; + int copyright; + int original; + int emphasis; + int error_protection; + +/* Back step buffers for mp3 */ + unsigned char bsspace[2][MAXFRAMESIZE + 512]; /* MAXFRAMESIZE */ + unsigned char *bsbuf, *bsbufold; + long ssize; + int init; + int single; + struct al_table *alloc; + int II_sblimit; + int jsbound; + int bo; /* Static variable in synthesizer */ + +/* MP3 Static arrays here */ + mpeg3_real_t synth_stereo_buffs[2][2][0x110]; + mpeg3_real_t synth_mono_buff[64]; + unsigned int layer2_scfsi_buf[64]; + + mpeg3_real_t mp3_block[2][2][SBLIMIT * SSLIMIT]; + int mp3_blc[2]; + +/* AC3 specific stuff. AC3 also shares objects with MPEG */ + unsigned int ac3_framesize_code; + mpeg3_ac3bsi_t ac3_bsi; + mpeg3_ac3audblk_t ac3_audblk; + mpeg3_ac3_bitallocation_t ac3_bit_allocation; + mpeg3_ac3_mantissa_t ac3_mantissa; + mpeg3_complex_t ac3_imdct_buf[AC3_N / 4]; + +/* Delay buffer for DCT interleaving */ + mpeg3_real_t ac3_delay[6][AC3_N / 2]; +/* Twiddle factor LUT */ + mpeg3_complex_t *ac3_w[7]; +#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES) + /* Just for allocated memory */ + mpeg3_complex_t ac3_w_1[1]; + mpeg3_complex_t ac3_w_2[2]; + mpeg3_complex_t ac3_w_4[4]; + mpeg3_complex_t ac3_w_8[8]; + mpeg3_complex_t ac3_w_16[16]; + mpeg3_complex_t ac3_w_32[32]; + mpeg3_complex_t ac3_w_64[64]; +#endif + int ac3_lfsr_state; + unsigned char ac3_buffer[MAX_AC3_FRAMESIZE]; + mpeg3ac3_stream_samples_t ac3_samples; +} mpeg3audio_t; + + + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/audio/mpeg3real.h b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3real.h new file mode 100644 index 0000000..cdcac3d --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3real.h @@ -0,0 +1,232 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3REAL_H +#define MPEG3REAL_H + +#ifdef USE_FIXED_POINT + +#include +#include + +#ifndef LONGLONG +#define LONGLONG long long +#endif + +//#define SC (1<<16) +#define SC (1<<15) + +class mpeg3_real_t { + long v; +public: + mpeg3_real_t() { } // Uninitialized, just like a float + mpeg3_real_t(double d) { v=long(d*SC); } + mpeg3_real_t(float f) { v=long(f*SC); } + mpeg3_real_t(int i) { v=long(i*SC); } + long fixedPoint() const { return v; } + operator float() const { return ((float)v)/SC; } + operator int() const { return (int)(v/SC); } + mpeg3_real_t operator+() const; + mpeg3_real_t operator-() const; + mpeg3_real_t& operator= (const mpeg3_real_t&); + mpeg3_real_t& operator+= (const mpeg3_real_t&); + mpeg3_real_t& operator-= (const mpeg3_real_t&); + mpeg3_real_t& operator*= (const mpeg3_real_t&); + mpeg3_real_t& operator/= (const mpeg3_real_t&); + friend mpeg3_real_t operator+ (const mpeg3_real_t&, const mpeg3_real_t&); + friend mpeg3_real_t operator- (const mpeg3_real_t&, const mpeg3_real_t&); + friend mpeg3_real_t operator* (const mpeg3_real_t&, const mpeg3_real_t&); + friend mpeg3_real_t operator/ (const mpeg3_real_t&, const mpeg3_real_t&); + friend mpeg3_real_t operator+ (const mpeg3_real_t&, const float&); + friend mpeg3_real_t operator- (const mpeg3_real_t&, const float&); + friend mpeg3_real_t operator* (const mpeg3_real_t&, const float&); + friend mpeg3_real_t operator/ (const mpeg3_real_t&, const float&); + friend mpeg3_real_t operator+ (const float&, const mpeg3_real_t&); + friend mpeg3_real_t operator- (const float&, const mpeg3_real_t&); + friend mpeg3_real_t operator* (const float&, const mpeg3_real_t&); + friend mpeg3_real_t operator/ (const float&, const mpeg3_real_t&); + friend mpeg3_real_t operator+ (const mpeg3_real_t&, const int&); + friend mpeg3_real_t operator- (const mpeg3_real_t&, const int&); + friend mpeg3_real_t operator* (const mpeg3_real_t&, const int&); + friend mpeg3_real_t operator/ (const mpeg3_real_t&, const int&); + friend mpeg3_real_t operator+ (const int&, const mpeg3_real_t&); + friend mpeg3_real_t operator- (const int&, const mpeg3_real_t&); + friend mpeg3_real_t operator* (const int&, const mpeg3_real_t&); + friend mpeg3_real_t operator/ (const int&, const mpeg3_real_t&); +}; + +inline mpeg3_real_t mpeg3_real_t::operator+() const +{ + return *this; +} + +inline mpeg3_real_t mpeg3_real_t::operator-() const +{ + mpeg3_real_t r; + r.v=-v; + return r; +} + +inline mpeg3_real_t& mpeg3_real_t::operator= (const mpeg3_real_t& o) +{ + v=o.v; + return *this; +} + +inline mpeg3_real_t& mpeg3_real_t::operator+= (const mpeg3_real_t& o) +{ + v += o.v; + return *this; +} + +inline mpeg3_real_t& mpeg3_real_t::operator-= (const mpeg3_real_t& o) +{ + v -= o.v; + return *this; +} + +inline mpeg3_real_t& mpeg3_real_t::operator*= (const mpeg3_real_t& o) +{ + *this = *this * o; + return *this; +} + +inline mpeg3_real_t& mpeg3_real_t::operator/= (const mpeg3_real_t& o) +{ + *this = *this / o; + return *this; +} + + +inline mpeg3_real_t operator+ (const mpeg3_real_t&a, const mpeg3_real_t&b) +{ + mpeg3_real_t r; + r.v=a.v+b.v; + return r; +} + +inline mpeg3_real_t operator- (const mpeg3_real_t&a, const mpeg3_real_t&b) +{ + mpeg3_real_t r; + r.v=a.v-b.v; + return r; +} + +inline mpeg3_real_t operator* (const mpeg3_real_t&a, const mpeg3_real_t&b) +{ + mpeg3_real_t r; + r.v = (LONGLONG)a.v * b.v / SC; + return r; +} + +inline mpeg3_real_t operator/ (const mpeg3_real_t&a, const mpeg3_real_t&b) +{ + mpeg3_real_t r; + r.v = (LONGLONG)a.v * SC / b.v; + return r; +} + +inline mpeg3_real_t operator+ (const mpeg3_real_t&a, const float&b) +{ + return a+mpeg3_real_t(b); +} + +inline mpeg3_real_t operator- (const mpeg3_real_t&a, const float&b) +{ + return a-mpeg3_real_t(b); +} + +inline mpeg3_real_t operator* (const mpeg3_real_t&a, const float&b) +{ + return a*mpeg3_real_t(b); +} + +inline mpeg3_real_t operator/ (const mpeg3_real_t&a, const float&b) +{ + return a/mpeg3_real_t(b); +} + + +inline mpeg3_real_t operator+ (const float&a, const mpeg3_real_t&b) +{ + return mpeg3_real_t(a)+b; +} + +inline mpeg3_real_t operator- (const float&a, const mpeg3_real_t&b) +{ + return mpeg3_real_t(a)-b; +} + +inline mpeg3_real_t operator* (const float&a, const mpeg3_real_t&b) +{ + return mpeg3_real_t(a)*b; +} + +inline mpeg3_real_t operator/ (const float&a, const mpeg3_real_t&b) +{ + return mpeg3_real_t(a)/b; +} + + +inline mpeg3_real_t operator+ (const mpeg3_real_t&a, const int&b) +{ + return a+mpeg3_real_t(b); +} + +inline mpeg3_real_t operator- (const mpeg3_real_t&a, const int&b) +{ + return a-mpeg3_real_t(b); +} + +inline mpeg3_real_t operator* (const mpeg3_real_t&a, const int&b) +{ + return a*mpeg3_real_t(b); +} + +inline mpeg3_real_t operator/ (const mpeg3_real_t&a, const int&b) +{ + return a/mpeg3_real_t(b); +} + + +inline mpeg3_real_t operator+ (const int&a, const mpeg3_real_t&b) +{ + return mpeg3_real_t(a)+b; +} + +inline mpeg3_real_t operator- (const int&a, const mpeg3_real_t&b) +{ + return mpeg3_real_t(a)-b; +} + +inline mpeg3_real_t operator* (const int&a, const mpeg3_real_t&b) +{ + return mpeg3_real_t(a)*b; +} + +inline mpeg3_real_t operator/ (const int&a, const mpeg3_real_t&b) +{ + return mpeg3_real_t(a)/b; +} + +#else +typedef float mpeg3_real_t; +#endif + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/audio/pcm.c b/core/multimedia/opieplayer/libmpeg3/audio/pcm.c new file mode 100644 index 0000000..8fa0d25 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/pcm.c @@ -0,0 +1,51 @@ +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" + +int mpeg3audio_read_pcm_header(mpeg3audio_t *audio) +{ + unsigned int code; + + code = mpeg3bits_getbits(audio->astream, 16); + while(!mpeg3bits_eof(audio->astream) && code != MPEG3_PCM_START_CODE) + { + code <<= 8; + code &= 0xffff; + code |= mpeg3bits_getbits(audio->astream, 8); + } + + audio->avg_framesize = audio->framesize = 0x7db; + audio->channels = 2; + + return mpeg3bits_eof(audio->astream); +} + +int mpeg3audio_do_pcm(mpeg3audio_t *audio) +{ + int i, j, k; + MPEG3_INT16 sample; + int frame_samples = (audio->framesize - 3) / audio->channels / 2; + + if(mpeg3bits_read_buffer(audio->astream, audio->ac3_buffer, frame_samples * audio->channels * 2)) + return 1; + +/* Need more room */ + if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels) + { + mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels); + } + + k = 0; + for(i = 0; i < frame_samples; i++) + { + for(j = 0; j < audio->channels; j++) + { + sample = ((MPEG3_INT16)(audio->ac3_buffer[k++])) << 8; + sample |= audio->ac3_buffer[k++]; + audio->pcm_sample[audio->pcm_point + i * audio->channels + j] = + (mpeg3_real_t)sample / 32767; + } + } + audio->pcm_point += frame_samples * audio->channels; + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/synthesizers.c b/core/multimedia/opieplayer/libmpeg3/audio/synthesizers.c new file mode 100644 index 0000000..71a74b3 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/synthesizers.c @@ -0,0 +1,174 @@ +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "tables.h" + +#define WRITE_SAMPLE(samples, sum) \ +{ \ + (*samples) = (sum); \ +} + +int mpeg3audio_synth_stereo(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, int channel, mpeg3_real_t *out, int *pnt) +{ + const int step = 2; + mpeg3_real_t *samples = out + *pnt; + register mpeg3_real_t sum; + mpeg3_real_t *b0, (*buf)[0x110]; + int bo1; + + if(!channel) + { + audio->bo--; + audio->bo &= 0xf; + buf = audio->synth_stereo_buffs[0]; + } + else + { + samples++; + buf = audio->synth_stereo_buffs[1]; + } + + if(audio->bo & 0x1) + { + b0 = buf[0]; + bo1 = audio->bo; + mpeg3audio_dct64(buf[1] + ((audio->bo + 1) & 0xf), buf[0] + audio->bo, bandPtr); + } + else + { + b0 = buf[1]; + bo1 = audio->bo + 1; + mpeg3audio_dct64(buf[0] + audio->bo, buf[1] + audio->bo + 1, bandPtr); + } + +/*printf("%f %f %f\n", buf[0][0], buf[1][0], bandPtr[0]); */ + + { + register int j; + mpeg3_real_t *window = mpeg3_decwin + 16 - bo1; + + for(j = 16; j; j--, b0 += 0x10, window += 0x20, samples += step) + { + sum = window[0x0] * b0[0x0]; + sum -= window[0x1] * b0[0x1]; + sum += window[0x2] * b0[0x2]; + sum -= window[0x3] * b0[0x3]; + sum += window[0x4] * b0[0x4]; + sum -= window[0x5] * b0[0x5]; + sum += window[0x6] * b0[0x6]; + sum -= window[0x7] * b0[0x7]; + sum += window[0x8] * b0[0x8]; + sum -= window[0x9] * b0[0x9]; + sum += window[0xA] * b0[0xA]; + sum -= window[0xB] * b0[0xB]; + sum += window[0xC] * b0[0xC]; + sum -= window[0xD] * b0[0xD]; + sum += window[0xE] * b0[0xE]; + sum -= window[0xF] * b0[0xF]; + + WRITE_SAMPLE(samples, sum); + } + + sum = window[0x0] * b0[0x0]; + sum += window[0x2] * b0[0x2]; + sum += window[0x4] * b0[0x4]; + sum += window[0x6] * b0[0x6]; + sum += window[0x8] * b0[0x8]; + sum += window[0xA] * b0[0xA]; + sum += window[0xC] * b0[0xC]; + sum += window[0xE] * b0[0xE]; + WRITE_SAMPLE(samples, sum); + b0 -= 0x10; + window -= 0x20; + samples += step; + window += bo1 << 1; + + for(j = 15; j; j--, b0 -= 0x10, window -= 0x20, samples += step) + { + sum = -window[-0x1] * b0[0x0]; + sum -= window[-0x2] * b0[0x1]; + sum -= window[-0x3] * b0[0x2]; + sum -= window[-0x4] * b0[0x3]; + sum -= window[-0x5] * b0[0x4]; + sum -= window[-0x6] * b0[0x5]; + sum -= window[-0x7] * b0[0x6]; + sum -= window[-0x8] * b0[0x7]; + sum -= window[-0x9] * b0[0x8]; + sum -= window[-0xA] * b0[0x9]; + sum -= window[-0xB] * b0[0xA]; + sum -= window[-0xC] * b0[0xB]; + sum -= window[-0xD] * b0[0xC]; + sum -= window[-0xE] * b0[0xD]; + sum -= window[-0xF] * b0[0xE]; + sum -= window[-0x0] * b0[0xF]; + + WRITE_SAMPLE(samples, sum); + } + } + *pnt += 64; + + return 0; +} + +int mpeg3audio_synth_mono(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, mpeg3_real_t *samples, int *pnt) +{ + mpeg3_real_t *samples_tmp = audio->synth_mono_buff; + mpeg3_real_t *tmp1 = samples_tmp; + int i, ret; + int pnt1 = 0; + + ret = mpeg3audio_synth_stereo(audio, bandPtr, 0, samples_tmp, &pnt1); + samples += *pnt; + + for(i = 0; i < 32; i++) + { + *samples = *tmp1; + samples++; + tmp1 += 2; + } + *pnt += 32; + + return ret; +} + + +/* Call this after every seek to reset the buffers */ +int mpeg3audio_reset_synths(mpeg3audio_t *audio) +{ + int i, j, k; + for(i = 0; i < 2; i++) + { + for(j = 0; j < 2; j++) + { + for(k = 0; k < 0x110; k++) + { + audio->synth_stereo_buffs[i][j][k] = 0; + } + } + } + for(i = 0; i < 64; i++) + { + audio->synth_mono_buff[i] = 0; + audio->layer2_scfsi_buf[i] = 0; + } + for(i = 0; i < 2; i++) + { + for(j = 0; j < 2; j++) + { + for(k = 0; k < SBLIMIT * SSLIMIT; k++) + { + audio->mp3_block[i][j][k] = 0; + } + } + } + audio->mp3_blc[0] = 0; + audio->mp3_blc[1] = 0; + for(i = 0; i < audio->channels; i++) + { + for(j = 0; j < AC3_N / 2; j++) + { + audio->ac3_delay[i][j] = 0; + } + } + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/tables.c b/core/multimedia/opieplayer/libmpeg3/audio/tables.c new file mode 100644 index 0000000..aeab335 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/tables.c @@ -0,0 +1,554 @@ +#include "mpeg3audio.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "tables.h" + +#include + +/* Bitrate indexes */ +int mpeg3_tabsel_123[2][3][16] = { + { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, + {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, + {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }, + + { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } +}; + +long mpeg3_freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 }; + +#ifdef USE_3DNOW +mpeg3_real_t mpeg3_decwin[2 * (512 + 32)]; +mpeg3_real_t mpeg3_cos64[32], mpeg3_cos32[16], mpeg3_cos16[8], mpeg3_cos8[4], mpeg3_cos4[2]; +#else +mpeg3_real_t mpeg3_decwin[512 + 32]; +mpeg3_real_t mpeg3_cos64[16], mpeg3_cos32[8], mpeg3_cos16[4], mpeg3_cos8[2], mpeg3_cos4[1]; +#endif + +mpeg3_real_t *mpeg3_pnts[] = { mpeg3_cos64, mpeg3_cos32, mpeg3_cos16, mpeg3_cos8, mpeg3_cos4 }; + +int mpeg3_grp_3tab[32 * 3] = { 0, }; /* used: 27 */ +int mpeg3_grp_5tab[128 * 3] = { 0, }; /* used: 125 */ +int mpeg3_grp_9tab[1024 * 3] = { 0, }; /* used: 729 */ + +REAL_MATRIX(mpeg3_muls, [27], [64]); /* also used by layer 1 */ +REAL_MATRIX(mpeg3_gainpow2, [256 + 118 + 4], ); +REAL_MATRIX(mpeg3_ispow, [8207], ); +REAL_MATRIX(mpeg3_aa_ca, [8], ); +REAL_MATRIX(mpeg3_aa_cs, [8], ); +REAL_MATRIX(mpeg3_win, [4], [36]); +REAL_MATRIX(mpeg3_win1, [4], [36]); +REAL_MATRIX(mpeg3_COS1, [12], [6]); +REAL_MATRIX(mpeg3_COS9, [9], ); +REAL_MATRIX(mpeg3_tfcos36, [9], ); +REAL_MATRIX(mpeg3_tfcos12, [3], ); +REAL_MATRIX(mpeg3_cos9, [3], ); +REAL_MATRIX(mpeg3_cos18, [3], ); +REAL_MATRIX(mpeg3_tan1_1, [16], ); +REAL_MATRIX(mpeg3_tan2_1, [16], ); +REAL_MATRIX(mpeg3_tan1_2, [16], ); +REAL_MATRIX(mpeg3_tan2_2, [16], ); +REAL_MATRIX(mpeg3_pow1_1, [2], [16]); +REAL_MATRIX(mpeg3_pow2_1, [2], [16]); +REAL_MATRIX(mpeg3_pow1_2, [2], [16]); +REAL_MATRIX(mpeg3_pow2_2, [2], [16]); + +mpeg3_real_t mpeg3_COS6_1, mpeg3_COS6_2; + +#ifdef PRINT_FIXED_POINT_TABLES +static void print_table(const char* var, mpeg3_real_t* data, int count) +{ + int i; + printf("#ifdef USE_DATA_TABLES\n"); + printf("static long %s_data[] = {",var); + for(i = 0; i < count; i++) { + printf("%c0x%08x,", i%8?' ':'\n', data[i].fixedPoint()); + } + printf("};\n"); + printf("#endif\n"); +} +#endif + +#ifdef PRINT_FIXED_POINT_TABLES +# define DO_TABLE(T) print_table(#T, T, sizeof(T)/sizeof(mpeg3_real_t)) +# define DO_TABLE2(T,DIM) print_table(#T, (mpeg3_real_t*)T, sizeof(T)/sizeof(mpeg3_real_t)) +#elif USE_FIXED_POINT +# define DO_TABLE(T) T = (mpeg3_real_t*)T##_data + // multidimensional +# define DO_TABLE2(T,DIM) T = (mpeg3_real_t(*)DIM)T##_data +#else +# define DO_TABLE(T) +# define DO_TABLE2(T,DIM) +#endif + +#if defined(USE_FIXED_POINT) && !defined(PRINT_FIXED_POINT_TABLES) +#define USE_DATA_TABLES +#include "fptables.h" +#endif + +long mpeg3_intwinbase[] = { + 0, -1, -1, -1, -1, -1, -1, -2, -2, -2, + -2, -3, -3, -4, -4, -5, -5, -6, -7, -7, + -8, -9, -10, -11, -13, -14, -16, -17, -19, -21, + -24, -26, -29, -31, -35, -38, -41, -45, -49, -53, + -58, -63, -68, -73, -79, -85, -91, -97, -104, -111, + -117, -125, -132, -139, -147, -154, -161, -169, -176, -183, + -190, -196, -202, -208, -213, -218, -222, -225, -227, -228, + -228, -227, -224, -221, -215, -208, -200, -189, -177, -163, + -146, -127, -106, -83, -57, -29, 2, 36, 72, 111, + 153, 197, 244, 294, 347, 401, 459, 519, 581, 645, + 711, 779, 848, 919, 991, 1064, 1137, 1210, 1283, 1356, + 1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962, + 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063, 2037, 2000, + 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970, + 794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388, + -1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, + -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209, + -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959, + -9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092, + -7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082, + -70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455, + 12980, 14548, 16155, 17799, 19478, 21189, 22929, 24694, 26482, 28289, + 30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617, + 48390, 50137, 51853, 53534, 55178, 56778, 58333, 59838, 61289, 62684, + 64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835, + 73415, 73908, 74313, 74630, 74856, 74992, 75038 }; + +int mpeg3_longLimit[9][23]; +int mpeg3_shortLimit[9][14]; + +struct mpeg3_bandInfoStruct mpeg3_bandInfo[9] = +{ + +/* MPEG 1.0 */ + { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576}, + {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158}, + {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3}, + {4,4,4,4,6,8,10,12,14,18,22,30,56} } , + + { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576}, + {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192}, + {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3}, + {4,4,4,4,6,6,10,12,14,16,20,26,66} } , + + { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} , + {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} , + {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} , + {4,4,4,4,6,8,12,16,20,26,34,42,12} } , + +/* MPEG 2.0 */ + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } , + {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} , + {4,4,4,6,6,8,10,14,18,26,32,42,18 } } , + + { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}, + {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } , + {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} , + {4,4,4,6,8,10,12,14,18,24,32,44,12 } } , + + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 }, + {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3}, + {4,4,4,6,8,10,12,14,18,24,30,40,18 } } , +/* MPEG 2.5 */ + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, + {0,12,24,36,54,78,108,144,186,240,312,402,522,576}, + {4,4,4,6,8,10,12,14,18,24,30,40,18} }, + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, + {0,12,24,36,54,78,108,144,186,240,312,402,522,576}, + {4,4,4,6,8,10,12,14,18,24,30,40,18} }, + { {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}, + {12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2}, + {0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576}, + {8,8,8,12,16,20,24,28,36,2,2,2,26} } , +}; + +int mpeg3_mapbuf0[9][152]; +int mpeg3_mapbuf1[9][156]; +int mpeg3_mapbuf2[9][44]; +int *mpeg3_map[9][3]; +int *mpeg3_mapend[9][3]; + +unsigned int mpeg3_n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */ +unsigned int mpeg3_i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */ + +int mpeg3audio_init_layer3(mpeg3audio_t *audio); + +int mpeg3audio_init_layer2(mpeg3audio_t *audio) +{ + static double mulmul[27] = + { + 0.0 , -2.0/3.0 , 2.0/3.0 , + 2.0/7.0 , 2.0/15.0 , 2.0/31.0, 2.0/63.0 , 2.0/127.0 , 2.0/255.0 , + 2.0/511.0 , 2.0/1023.0 , 2.0/2047.0 , 2.0/4095.0 , 2.0/8191.0 , + 2.0/16383.0 , 2.0/32767.0 , 2.0/65535.0 , + -4.0/5.0 , -2.0/5.0 , 2.0/5.0, 4.0/5.0 , + -8.0/9.0 , -4.0/9.0 , -2.0/9.0 , 2.0/9.0 , 4.0/9.0 , 8.0/9.0 + }; + static int base[3][9] = + { + { 1 , 0, 2 , } , + { 17, 18, 0 , 19, 20 , } , + { 21, 1, 22, 23, 0, 24, 25, 2, 26 } + }; + static int tablen[3] = { 3, 5, 9 }; + static int *itable, *tables[3] = {mpeg3_grp_3tab, mpeg3_grp_5tab, mpeg3_grp_9tab}; + int i, j, k, l, len; + mpeg3_real_t *table; + + for(i = 0; i < 3; i++) + { + itable = tables[i]; + len = tablen[i]; + for(j = 0; j < len; j++) + for(k = 0; k < len; k++) + for(l = 0; l < len; l++) + { + *itable++ = base[i][l]; + *itable++ = base[i][k]; + *itable++ = base[i][j]; + } + } + +#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES) +#if defined(PRINT_FIXED_POINT_TABLES) + //mpeg3audio_init_layer3(audio); // we depend on mpeg3_muls table +#endif + for(k = 0; k < 27; k++) + { + double m = mulmul[k]; + table = mpeg3_muls[k]; + for(j = 3, i = 0; i < 63; i++, j--) + *table++ = m * pow(2.0, (double)j / 3.0); + *table++ = 0.0; + } +#endif + DO_TABLE2(mpeg3_muls,[64]); + return 0; +} + +int mpeg3audio_init_layer3(mpeg3audio_t *audio) +{ + int i, j, k, l; + int down_sample_sblimit = 32; + + audio->mp3_block[0][0][0] = 0; + audio->mp3_blc[0] = 0; + audio->mp3_blc[1] = 0; + +#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES) + for(i = -256; i < 118 + 4; i++) + mpeg3_gainpow2[i + 256] = pow((double)2.0, -0.25 * (double)(i + 210)); + + for(i = 0; i < 8207; i++) + mpeg3_ispow[i] = pow((double)i, (double)4.0 / 3.0); + + for(i = 0; i < 8; i++) + { + static double Ci[8] = {-0.6,-0.535,-0.33,-0.185,-0.095,-0.041,-0.0142,-0.0037}; + double sq = sqrt(1.0+Ci[i]*Ci[i]); + mpeg3_aa_cs[i] = 1.0/sq; + mpeg3_aa_ca[i] = Ci[i]/sq; + } + + for(i = 0; i < 18; i++) + { + mpeg3_win[0][i] = mpeg3_win[1][i] = 0.5 * sin( M_PI / 72.0 * (double)(2 * (i + 0) + 1) ) / cos (M_PI * (double)(2 * (i + 0) + 19) / 72.0); + mpeg3_win[0][i+18] = mpeg3_win[3][i+18] = 0.5 * sin( M_PI / 72.0 * (double)(2 * (i + 18) + 1) ) / cos (M_PI * (double)(2 * (i + 18) + 19) / 72.0); + } + for(i = 0; i < 6; i++) + { + mpeg3_win[1][i + 18] = 0.5 / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 ); + mpeg3_win[3][i + 12] = 0.5 / cos ( M_PI * (double) (2*(i+12)+19) / 72.0 ); + mpeg3_win[1][i + 24] = 0.5 * sin( M_PI / 24.0 * (double)(2 * i + 13) ) / cos (M_PI * (double)(2 * (i + 24)+ 19) / 72.0 ); + mpeg3_win[1][i + 30] = mpeg3_win[3][i] = 0.0; + mpeg3_win[3][i + 6 ] = 0.5 * sin( M_PI / 24.0 * (double)(2 * i + 1) ) / cos (M_PI * (double)(2 * (i + 6 )+ 19) / 72.0 ); + } + + for(i = 0; i < 9; i++) + mpeg3_COS9[i] = cos(M_PI / 18.0 * (double)i); + + for(i = 0; i < 9; i++) + mpeg3_tfcos36[i] = 0.5 / cos (M_PI * (double) (i*2+1) / 36.0); + for(i = 0; i < 3; i++) + mpeg3_tfcos12[i] = 0.5 / cos (M_PI * (double) (i*2+1) / 12.0); + + mpeg3_cos9[0] = cos(1.0 * M_PI / 9.0); + mpeg3_cos9[1] = cos(5.0 * M_PI / 9.0); + mpeg3_cos9[2] = cos(7.0 * M_PI / 9.0); + mpeg3_cos18[0] = cos(1.0 * M_PI / 18.0); + mpeg3_cos18[1] = cos(11.0 * M_PI / 18.0); + mpeg3_cos18[2] = cos(13.0 * M_PI / 18.0); + + for(i = 0; i < 12; i++) + { + mpeg3_win[2][i] = 0.5 * sin(M_PI / 24.0 * (double) (2 * i + 1)) / cos(M_PI * (double)(2 * i + 7) / 24.0); + for(j = 0; j < 6; j++) + mpeg3_COS1[i][j] = cos(M_PI / 24.0 * (double) ((2 * i + 7) * (2 * j + 1))); + } + + for(j = 0; j < 4; j++) + { + static int len[4] = {36, 36, 12, 36}; + for(i = 0; i < len[j]; i += 2) + mpeg3_win1[j][i] = + mpeg3_win[j][i]; + for(i = 1; i < len[j]; i += 2) + mpeg3_win1[j][i] = - mpeg3_win[j][i]; + } + + for(i = 0; i < 16; i++) + { + double t = tan( (double) i * M_PI / 12.0 ); + mpeg3_tan1_1[i] = t / (1.0 + t); + mpeg3_tan2_1[i] = 1.0 / (1.0 + t); + mpeg3_tan1_2[i] = M_SQRT2 * t / (1.0 + t); + mpeg3_tan2_2[i] = M_SQRT2 / (1.0 + t); + + for(j = 0; j < 2; j++) + { + double base = pow(2.0, -0.25 * (j + 1.0)); + double p1 = 1.0,p2 = 1.0; + if(i > 0) + { + if( i & 1 ) + p1 = pow(base, (i + 1.0) * 0.5); + else + p2 = pow(base, i * 0.5); + } + mpeg3_pow1_1[j][i] = p1; + mpeg3_pow2_1[j][i] = p2; + mpeg3_pow1_2[j][i] = M_SQRT2 * p1; + mpeg3_pow2_2[j][i] = M_SQRT2 * p2; + } + } + +#endif + + DO_TABLE(mpeg3_gainpow2); + DO_TABLE(mpeg3_ispow); + DO_TABLE(mpeg3_aa_cs); + DO_TABLE(mpeg3_aa_ca); + DO_TABLE2(mpeg3_win,[36]); + DO_TABLE(mpeg3_COS9); + DO_TABLE(mpeg3_tfcos36); + DO_TABLE(mpeg3_tfcos12); + DO_TABLE(mpeg3_cos9); + DO_TABLE(mpeg3_cos18); + DO_TABLE2(mpeg3_COS1,[6]); + DO_TABLE2(mpeg3_win1,[36]); + DO_TABLE(mpeg3_tan1_1); + DO_TABLE(mpeg3_tan2_1); + DO_TABLE(mpeg3_tan1_2); + DO_TABLE(mpeg3_tan2_2); + DO_TABLE2(mpeg3_pow1_1,[16]); + DO_TABLE2(mpeg3_pow2_1,[16]); + DO_TABLE2(mpeg3_pow1_2,[16]); + DO_TABLE2(mpeg3_pow2_2,[16]); + + mpeg3_COS6_1 = cos( M_PI / 6.0 * (double) 1); + mpeg3_COS6_2 = cos( M_PI / 6.0 * (double) 2); + + for(j = 0; j < 9; j++) + { + struct mpeg3_bandInfoStruct *bi = &mpeg3_bandInfo[j]; + int *mp; + int cb,lwin; + int *bdf; + + mp = mpeg3_map[j][0] = mpeg3_mapbuf0[j]; + bdf = bi->longDiff; + for(i = 0, cb = 0; cb < 8; cb++, i += *bdf++) + { + *mp++ = (*bdf) >> 1; + *mp++ = i; + *mp++ = 3; + *mp++ = cb; + } + bdf = bi->shortDiff + 3; + for(cb = 3; cb < 13; cb++) + { + int l = (*bdf++) >> 1; + for(lwin = 0; lwin < 3; lwin++) + { + *mp++ = l; + *mp++ = i + lwin; + *mp++ = lwin; + *mp++ = cb; + } + i += 6 * l; + } + mpeg3_mapend[j][0] = mp; + + mp = mpeg3_map[j][1] = mpeg3_mapbuf1[j]; + bdf = bi->shortDiff+0; + for(i = 0,cb = 0; cb < 13; cb++) + { + int l = (*bdf++) >> 1; + for(lwin = 0; lwin < 3; lwin++) + { + *mp++ = l; + *mp++ = i + lwin; + *mp++ = lwin; + *mp++ = cb; + } + i += 6 * l; + } + mpeg3_mapend[j][1] = mp; + + mp = mpeg3_map[j][2] = mpeg3_mapbuf2[j]; + bdf = bi->longDiff; + for(cb = 0; cb < 22 ; cb++) + { + *mp++ = (*bdf++) >> 1; + *mp++ = cb; + } + mpeg3_mapend[j][2] = mp; + } + + for(j = 0; j < 9; j++) + { + for(i = 0; i < 23; i++) + { + mpeg3_longLimit[j][i] = (mpeg3_bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1; + if(mpeg3_longLimit[j][i] > (down_sample_sblimit)) + mpeg3_longLimit[j][i] = down_sample_sblimit; + } + for(i = 0; i < 14; i++) + { + mpeg3_shortLimit[j][i] = (mpeg3_bandInfo[j].shortIdx[i] - 1) / 18 + 1; + if(mpeg3_shortLimit[j][i] > (down_sample_sblimit) ) + mpeg3_shortLimit[j][i] = down_sample_sblimit; + } + } + + for(i = 0; i < 5; i++) + { + for(j = 0; j < 6; j++) + { + for(k = 0; k < 6; k++) + { + int n = k + j * 6 + i * 36; + mpeg3_i_slen2[n] = i | (j << 3) | (k << 6) | (3 << 12); + } + } + } + for(i = 0; i < 4; i++) + { + for(j = 0; j < 4; j++) + { + for(k = 0; k < 4; k++) + { + int n = k + j * 4 + i * 16; + mpeg3_i_slen2[n+180] = i | (j << 3) | (k << 6) | (4 << 12); + } + } + } + for(i = 0; i < 4; i++) + { + for(j = 0; j < 3; j++) + { + int n = j + i * 3; + mpeg3_i_slen2[n + 244] = i | (j << 3) | (5 << 12); + mpeg3_n_slen2[n + 500] = i | (j << 3) | (2 << 12) | (1 << 15); + } + } + + for(i = 0; i < 5; i++) + { + for(j = 0; j < 5; j++) + { + for(k = 0; k < 4; k++) + { + for(l = 0; l < 4; l++) + { + int n = l + k * 4 + j * 16 + i * 80; + mpeg3_n_slen2[n] = i | (j << 3) | ( k << 6) | (l << 9) | (0 << 12); + } + } + } + } + for(i = 0; i < 5; i++) + { + for(j = 0; j < 5; j++) + { + for(k = 0; k < 4; k++) + { + int n = k + j * 4 + i * 20; + mpeg3_n_slen2[n + 400] = i | (j << 3) | (k << 6) | (1 << 12); + } + } + } + + return 0; +} + +int mpeg3audio_new_decode_tables(mpeg3audio_t *audio) +{ + int i, j, k, kr, divv; + mpeg3_real_t *costab; + int idx; + long scaleval = audio->outscale; + + + for(i = 0; i < 5; i++) + { + kr = 0x10 >> i; + divv = 0x40 >> i; + costab = mpeg3_pnts[i]; + for(k = 0; k < kr; k++) + costab[k] = 1.0 / (2.0 * cos(M_PI * ((double)k * 2.0 + 1.0) / (double)divv)); + +#ifdef USE_3DNOW + for(k = 0; k < kr; k++) + costab[k + kr] = -costab[k]; +#endif + + } + + idx = 0; + scaleval = -scaleval; + for(i = 0, j = 0; i < 256; i++, j++,idx += 32) + { + if(idx < 512 + 16) + mpeg3_decwin[idx+16] = mpeg3_decwin[idx] = (double)mpeg3_intwinbase[j] / 65536.0 * (double)scaleval; + + if(i % 32 == 31) + idx -= 1023; + if(i % 64 == 63) + scaleval = -scaleval; + } + + for( ; i < 512; i++, j--, idx += 32) + { + if(idx < 512 + 16) + mpeg3_decwin[idx + 16] = mpeg3_decwin[idx] = (double)mpeg3_intwinbase[j] / 65536.0 * (double)scaleval; + + if(i % 32 == 31) + idx -= 1023; + if(i % 64 == 63) + scaleval = -scaleval; + } + +#ifdef USE_3DNOW + if(!param.down_sample) + { + for(i = 0; i < 512 + 32; i++) + { + mpeg3_decwin[512 + 31 - i] *= 65536.0; /* allows faster clipping in 3dnow code */ + mpeg3_decwin[512 + 32 + i] = mpeg3_decwin[512 + 31 - i]; + } + } +#endif + +/* Initialize AC3 */ + audio->ac3_lfsr_state = 1; + mpeg3audio_imdct_init(audio); +/* Initialize MPEG */ + mpeg3audio_init_layer2(audio); /* inits also shared tables with layer1 */ + mpeg3audio_init_layer3(audio); + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/audio/tables.h b/core/multimedia/opieplayer/libmpeg3/audio/tables.h new file mode 100644 index 0000000..7b14de1 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/tables.h @@ -0,0 +1,88 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef TABLES_H +#define TABLES_H + +extern int mpeg3_tabsel_123[2][3][16]; + +extern long mpeg3_freqs[9]; + +struct mpeg3_bandInfoStruct +{ + int longIdx[23]; + int longDiff[22]; + int shortIdx[14]; + int shortDiff[13]; +}; + + +extern mpeg3_real_t mpeg3_decwin[512 + 32]; +extern mpeg3_real_t mpeg3_cos64[16], mpeg3_cos32[8], mpeg3_cos16[4], mpeg3_cos8[2], mpeg3_cos4[1]; + +extern mpeg3_real_t *mpeg3_pnts[5]; + +extern int mpeg3_grp_3tab[32 * 3]; /* used: 27 */ +extern int mpeg3_grp_5tab[128 * 3]; /* used: 125 */ +extern int mpeg3_grp_9tab[1024 * 3]; /* used: 729 */ +extern long mpeg3_intwinbase[257]; +extern mpeg3_real_t mpeg3_COS6_1, mpeg3_COS6_2; + +#if defined(USE_FIXED_POINT) && !defined(PRINT_FIXED_POINT_TABLES) +# define REAL_MATRIX(var,dim1,dimn) mpeg3_real_t (*var)dimn +#else +# define REAL_MATRIX(var,dim1,dimn) mpeg3_real_t var dim1 dimn +#endif +extern REAL_MATRIX(mpeg3_muls, [27], [64]); /* also used by layer 1 */ +extern REAL_MATRIX(mpeg3_gainpow2, [256 + 118 + 4], ); +extern REAL_MATRIX(mpeg3_ispow, [8207], ); +extern REAL_MATRIX(mpeg3_aa_ca, [8], ); +extern REAL_MATRIX(mpeg3_aa_cs, [8], ); +extern REAL_MATRIX(mpeg3_win, [4], [36]); +extern REAL_MATRIX(mpeg3_win1, [4], [36]); +extern REAL_MATRIX(mpeg3_COS1, [12], [6]); +extern REAL_MATRIX(mpeg3_COS9, [9], ); +extern REAL_MATRIX(mpeg3_tfcos36, [9], ); +extern REAL_MATRIX(mpeg3_tfcos12, [3], ); +extern REAL_MATRIX(mpeg3_cos9, [3], ); +extern REAL_MATRIX(mpeg3_cos18, [3], ); +extern REAL_MATRIX(mpeg3_tan1_1, [16], ); +extern REAL_MATRIX(mpeg3_tan2_1, [16], ); +extern REAL_MATRIX(mpeg3_tan1_2, [16], ); +extern REAL_MATRIX(mpeg3_tan2_2, [16], ); +extern REAL_MATRIX(mpeg3_pow1_1, [2], [16]); +extern REAL_MATRIX(mpeg3_pow2_1, [2], [16]); +extern REAL_MATRIX(mpeg3_pow1_2, [2], [16]); +extern REAL_MATRIX(mpeg3_pow2_2, [2], [16]); + +extern int mpeg3_longLimit[9][23]; +extern int mpeg3_shortLimit[9][14]; + +extern struct mpeg3_bandInfoStruct mpeg3_bandInfo[9]; + +extern int mpeg3_mapbuf0[9][152]; +extern int mpeg3_mapbuf1[9][156]; +extern int mpeg3_mapbuf2[9][44]; +extern int *mpeg3_map[9][3]; +extern int *mpeg3_mapend[9][3]; + +extern unsigned int mpeg3_n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */ +extern unsigned int mpeg3_i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */ + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/audio/uncouple.c b/core/multimedia/opieplayer/libmpeg3/audio/uncouple.c new file mode 100644 index 0000000..d87a078 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/audio/uncouple.c @@ -0,0 +1,135 @@ +/* + * + * uncouple.c Copyright (C) Aaron Holtzman - May 1999 + * + * This file is part of libmpeg3 + * + * libmpeg3 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * libmpeg3 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "../bitstream.h" +#include "mpeg3audio.h" + +static unsigned char mpeg3_first_bit_lut[256] = +{ + 0, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +/* Converts an unsigned exponent in the range of 0-24 and a 16 bit mantissa + * to an IEEE single precision floating point value */ +static inline void mpeg3audio_ac3_convert_to_float(unsigned short exp, + unsigned short mantissa, + unsigned MPEG3_INT32 *dest) +{ + int num; + short exponent; + int i; + +/* If the mantissa is zero we can simply return zero */ + if(mantissa == 0) + { + *dest = 0; + return; + } + +/* Exponent is offset by 127 in IEEE format minus the shift to + * align the mantissa to 1.f (subtracted in the final result) */ + exponent = 127 - exp; + +/* Take care of the one asymmetric negative number */ + if(mantissa == 0x8000) + mantissa++; + +/* Extract the sign bit, invert the mantissa if it's negative, and + shift out the sign bit */ + if(mantissa & 0x8000) + { + mantissa *= -1; + num = 0x80000000 + (exponent << 23); + } + else + { + mantissa *= 1; + num = exponent << 23; + } + +/* Find the index of the most significant one bit */ + i = mpeg3_first_bit_lut[mantissa >> 8]; + + if(i == 0) + i = mpeg3_first_bit_lut[mantissa & 0xff] + 8; + + *dest = num - (i << 23) + (mantissa << (7 + i)); + return; +} + + +int mpeg3audio_ac3_uncouple(mpeg3audio_t *audio, + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk, + mpeg3_stream_coeffs_t *coeffs) +{ + int i, j; + + for(i = 0; i < bsi->nfchans; i++) + { + for(j = 0; j < audblk->endmant[i]; j++) + mpeg3audio_ac3_convert_to_float(audblk->fbw_exp[i][j], + audblk->chmant[i][j], + (unsigned MPEG3_INT32*)&coeffs->fbw[i][j]); + } + + if(audblk->cplinu) + { + for(i = 0; i < bsi->nfchans; i++) + { + if(audblk->chincpl[i]) + { + mpeg3audio_ac3_uncouple_channel(audio, + coeffs, + audblk, + i); + } + } + + } + + if(bsi->lfeon) + { +/* There are always 7 mantissas for lfe */ + for(j = 0; j < 7 ; j++) + mpeg3audio_ac3_convert_to_float(audblk->lfe_exp[j], + audblk->lfemant[j], + (unsigned MPEG3_INT32*)&coeffs->lfe[j]); + + } + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/bitstream.c b/core/multimedia/opieplayer/libmpeg3/bitstream.c new file mode 100644 index 0000000..b4f46e3 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/bitstream.c @@ -0,0 +1,167 @@ +#include "mpeg3private.h" +#include "mpeg3protos.h" + +#include + +mpeg3_bits_t* mpeg3bits_new_stream(mpeg3_t *file, mpeg3_demuxer_t *demuxer) +{ + mpeg3_bits_t *stream = (mpeg3_bits_t*)malloc(sizeof(mpeg3_bits_t)); + stream->bfr = 0; + stream->bfr_size = 0; + stream->bit_number = 0; + stream->file = file; + stream->demuxer = demuxer; + stream->input_ptr = 0; + return stream; +} + +int mpeg3bits_delete_stream(mpeg3_bits_t* stream) +{ + free(stream); + return 0; +} + + +/* Fill a buffer. Only works if bit_number is on an 8 bit boundary */ +int mpeg3bits_read_buffer(mpeg3_bits_t* stream, unsigned char *buffer, int bytes) +{ + int result, i = 0; + while(stream->bit_number > 0) + { + stream->bit_number -= 8; + mpeg3demux_read_prev_char(stream->demuxer); + } + + stream->bit_number = 0; + stream->bfr_size = 0; + stream->bfr = 0; + result = mpeg3demux_read_data(stream->demuxer, buffer, bytes); + return result; +} + +/* For mp3 decompression use a pointer in a buffer for getbits. */ +int mpeg3bits_use_ptr(mpeg3_bits_t* stream, unsigned char *buffer) +{ + stream->bfr_size = stream->bit_number = 0; + stream->bfr = 0; + stream->input_ptr = buffer; + return 0; +} + +/* Go back to using the demuxer for getbits in mp3. */ +int mpeg3bits_use_demuxer(mpeg3_bits_t* stream) +{ + if(stream->input_ptr) + { + stream->bfr_size = stream->bit_number = 0; + stream->input_ptr = 0; + stream->bfr = 0; + } + + return 0; +} + +/* Reconfigure for reverse operation */ +/* Default is forward operation */ +void mpeg3bits_start_reverse(mpeg3_bits_t* stream) +{ + int i; + for(i = 0; i < stream->bfr_size; i += 8) + if(stream->input_ptr) + stream->input_ptr--; + else + mpeg3demux_read_prev_char(stream->demuxer); +} + +/* Reconfigure for forward operation */ +void mpeg3bits_start_forward(mpeg3_bits_t* stream) +{ + int i; + for(i = 0; i < stream->bfr_size; i += 8) + if(stream->input_ptr) + stream->input_ptr++; + else + mpeg3demux_read_char(stream->demuxer); +} + +/* Erase the buffer with the next 4 bytes in the file. */ +int mpeg3bits_refill(mpeg3_bits_t* stream) +{ + stream->bit_number = 32; + stream->bfr_size = 32; + + if(stream->input_ptr) + { + stream->bfr = (unsigned int)(*stream->input_ptr++) << 24; + stream->bfr |= (unsigned int)(*stream->input_ptr++) << 16; + stream->bfr |= (unsigned int)(*stream->input_ptr++) << 8; + stream->bfr |= *stream->input_ptr++; + } + else + { + stream->bfr = mpeg3demux_read_char(stream->demuxer) << 24; + stream->bfr |= mpeg3demux_read_char(stream->demuxer) << 16; + stream->bfr |= mpeg3demux_read_char(stream->demuxer) << 8; + stream->bfr |= mpeg3demux_read_char(stream->demuxer); + } + return mpeg3demux_eof(stream->demuxer); +} + +/* Erase the buffer with the previous 4 bytes in the file. */ +int mpeg3bits_refill_backwards(mpeg3_bits_t* stream) +{ + stream->bit_number = 0; + stream->bfr_size = 32; + stream->bfr = mpeg3demux_read_prev_char(stream->demuxer); + stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << 8; + stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << 16; + stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << 24; + return mpeg3demux_eof(stream->demuxer); +} + +int mpeg3bits_byte_align(mpeg3_bits_t *stream) +{ + stream->bit_number = (stream->bit_number + 7) & 0xf8; + return 0; +} + +int mpeg3bits_seek_end(mpeg3_bits_t* stream) +{ + stream->bfr_size = stream->bit_number = 0; + return mpeg3demux_seek_byte(stream->demuxer, mpeg3demuxer_total_bytes(stream->demuxer)); +} + +int mpeg3bits_seek_start(mpeg3_bits_t* stream) +{ + stream->bfr_size = stream->bit_number = 0; + return mpeg3demux_seek_byte(stream->demuxer, 0); +} + +int mpeg3bits_seek_time(mpeg3_bits_t* stream, double time_position) +{ + stream->bfr_size = stream->bit_number = 0; + return mpeg3demux_seek_time(stream->demuxer, time_position); +} + +int mpeg3bits_seek_byte(mpeg3_bits_t* stream, long position) +{ + stream->bfr_size = stream->bit_number = 0; + return mpeg3demux_seek_byte(stream->demuxer, position); +} + +int mpeg3bits_seek_percentage(mpeg3_bits_t* stream, double percentage) +{ + stream->bfr_size = stream->bit_number = 0; + return mpeg3demux_seek_percentage(stream->demuxer, percentage); +} + +int mpeg3bits_tell(mpeg3_bits_t* stream) +{ + return mpeg3demux_tell(stream->demuxer); +} + +int mpeg3bits_getbitoffset(mpeg3_bits_t *stream) +{ + return stream->bit_number & 7; +} + diff --git a/core/multimedia/opieplayer/libmpeg3/bitstream.h b/core/multimedia/opieplayer/libmpeg3/bitstream.h new file mode 100644 index 0000000..2f6dcf9 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/bitstream.h @@ -0,0 +1,207 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef BITSTREAM_H +#define BITSTREAM_H + +#include "mpeg3demux.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +// next bit in forward direction +// next bit in reverse direction | +// v v +// | | | | | | | | | | | | | | | | | | | | | | | | | | |1|1|1|1|1|1| */ +// ^ ^ +// | bit_number = 1 +// bfr_size = 6 + +typedef struct +{ + unsigned MPEG3_INT32 bfr; /* bfr = buffer for bits */ + int bit_number; /* position of pointer in bfr */ + int bfr_size; /* number of bits in bfr. Should always be a multiple of 8 */ + struct mpeg3_rec *file; /* Mpeg2 file */ + mpeg3_demuxer_t *demuxer; /* Mpeg2 demuxer */ +/* If the input ptr is true, data is read from it instead of the demuxer. */ + unsigned char *input_ptr; +} mpeg3_bits_t; + +LIBMPEG_EXPORT unsigned int mpeg3demux_read_char_packet(mpeg3_demuxer_t *demuxer); +LIBMPEG_EXPORT unsigned int mpeg3demux_read_prev_char_packet(mpeg3_demuxer_t *demuxer); + +/* ======================================================================== */ +/* Entry Points */ +/* ======================================================================== */ + +#define mpeg3bits_tell_percentage(stream) mpeg3demux_tell_percentage((stream)->demuxer) + +#define mpeg3bits_packet_time(stream) mpeg3demux_current_time((stream)->demuxer) + +#define mpeg3bits_time_offset(stream) mepg2demux_time_offset((stream)->demuxer) + +#define mpeg3bits_error(stream) mpeg3demux_error((stream)->demuxer) + +#define mpeg3bits_eof(stream) mpeg3demux_eof((stream)->demuxer) + +#define mpeg3bits_bof(stream) mpeg3demux_bof((stream)->demuxer) + +/* Read bytes backward from the file until the reverse_bits is full. */ +static inline void mpeg3bits_fill_reverse_bits(mpeg3_bits_t* stream, int bits) +{ +// Right justify + while(stream->bit_number > 7) + { + stream->bfr >>= 8; + stream->bfr_size -= 8; + stream->bit_number -= 8; + } + +// Insert bytes before bfr_size + while(stream->bfr_size - stream->bit_number < bits) + { + if(stream->input_ptr) + stream->bfr |= (unsigned int)(*--stream->input_ptr) << stream->bfr_size; + else + stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << stream->bfr_size; + stream->bfr_size += 8; + } +} + +/* Read bytes forward from the file until the forward_bits is full. */ +extern inline void mpeg3bits_fill_bits(mpeg3_bits_t* stream, int bits) +{ + while(stream->bit_number < bits) + { + stream->bfr <<= 8; + if(stream->input_ptr) + { + stream->bfr |= *stream->input_ptr++; + } + else + { + stream->bfr |= mpeg3demux_read_char(stream->demuxer); + } + stream->bit_number += 8; + stream->bfr_size += 8; + if(stream->bfr_size > 32) stream->bfr_size = 32; + } +} + +/* Return 8 bits, advancing the file position. */ +extern inline unsigned int mpeg3bits_getbyte_noptr(mpeg3_bits_t* stream) +{ + if(stream->bit_number < 8) + { + stream->bfr <<= 8; + if(stream->input_ptr) + stream->bfr |= *stream->input_ptr++; + else + stream->bfr |= mpeg3demux_read_char(stream->demuxer); + + stream->bfr_size += 8; + if(stream->bfr_size > 32) stream->bfr_size = 32; + + return (stream->bfr >> stream->bit_number) & 0xff; + } + return (stream->bfr >> (stream->bit_number -= 8)) & 0xff; +} + +extern inline unsigned int mpeg3bits_getbit_noptr(mpeg3_bits_t* stream) +{ + if(!stream->bit_number) + { + stream->bfr <<= 8; + stream->bfr |= mpeg3demux_read_char(stream->demuxer); + + stream->bfr_size += 8; + if(stream->bfr_size > 32) stream->bfr_size = 32; + + stream->bit_number = 7; + + return (stream->bfr >> 7) & 0x1; + } + return (stream->bfr >> (--stream->bit_number)) & (0x1); +} + +/* Return n number of bits, advancing the file position. */ +/* Use in place of flushbits */ +extern inline unsigned int mpeg3bits_getbits(mpeg3_bits_t* stream, int bits) +{ + if(bits <= 0) return 0; + mpeg3bits_fill_bits(stream, bits); + return (stream->bfr >> (stream->bit_number -= bits)) & (0xffffffff >> (32 - bits)); +} + +extern inline unsigned int mpeg3bits_showbits24_noptr(mpeg3_bits_t* stream) +{ + while(stream->bit_number < 24) + { + stream->bfr <<= 8; + stream->bfr |= mpeg3demux_read_char(stream->demuxer); + stream->bit_number += 8; + stream->bfr_size += 8; + if(stream->bfr_size > 32) stream->bfr_size = 32; + } + return (stream->bfr >> (stream->bit_number - 24)) & 0xffffff; +} + +extern inline unsigned int mpeg3bits_showbits32_noptr(mpeg3_bits_t* stream) +{ + while(stream->bit_number < 32) + { + stream->bfr <<= 8; + stream->bfr |= mpeg3demux_read_char(stream->demuxer); + stream->bit_number += 8; + stream->bfr_size += 8; + if(stream->bfr_size > 32) stream->bfr_size = 32; + } + return stream->bfr; +} + +extern inline unsigned int mpeg3bits_showbits(mpeg3_bits_t* stream, int bits) +{ + mpeg3bits_fill_bits(stream, bits); + return (stream->bfr >> (stream->bit_number - bits)) & (0xffffffff >> (32 - bits)); +} + +extern inline unsigned int mpeg3bits_getbits_reverse(mpeg3_bits_t* stream, int bits) +{ + unsigned int result; + mpeg3bits_fill_reverse_bits(stream, bits); + result = (stream->bfr >> stream->bit_number) & (0xffffffff >> (32 - bits)); + stream->bit_number += bits; + return result; +} + +extern inline unsigned int mpeg3bits_showbits_reverse(mpeg3_bits_t* stream, int bits) +{ + unsigned int result; + mpeg3bits_fill_reverse_bits(stream, bits); + result = (stream->bfr >> stream->bit_number) & (0xffffffff >> (32 - bits)); + return result; +} + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/c_flags b/core/multimedia/opieplayer/libmpeg3/c_flags new file mode 100755 index 0000000..0c8a75d --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/c_flags @@ -0,0 +1,4 @@ +case "$1" in + *.c) echo $CFLAGS_lessopt +;; *) echo $CFLAGS +esac diff --git a/core/multimedia/opieplayer/libmpeg3/configure b/core/multimedia/opieplayer/libmpeg3/configure new file mode 100755 index 0000000..e75af76 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/configure @@ -0,0 +1,102 @@ +#!/bin/sh + +USE_MMX=1 +USE_CSS=1 +LESS_OPT= +PLATFORM_CFLAGS="-malign-loops=2 -malign-jumps=2 -malign-functions=2 -march=i486" +DEBUG= +OPTIMIZE=-O2 +OPTIMIZE_less=-O +DEFINES= +CC=gcc + +for ac_option +do +case "$ac_option" in + --fixed-point) + CC=g++ + DEFINES="$DEFINES -DUSE_FIXED_POINT" + ;; + + --lessopt) + LESS_OPT=1 + ;; + + --no-mmx) + USE_MMX=0 + ;; + + --no-css) + USE_CSS=0 + ;; + + --debug) + DEBUG=-g + ;; + + --gcc-prefix=*) + CROSS=${ac_option#--gcc-prefix=} + PLATFORM_CFLAGS="" + ;; + -h | --help | -help) + cat << EOF +Options: + --no-mmx Compile libmpeg3 with no MMX support. + --no-css Compile libmpeg3 with no CSS support. + --fixed-point Compile libmpeg3 to use integers instead of floats. + --debug Compile libmpeg3 with debug support. +EOF + exit 0 + ;; + + *) + ;; +esac +done + + +echo "Configuring libmpeg3" + +cat > global_config << EOF +# DO NOT EDIT. EDIT ./configure INSTEAD AND RERUN IT. +EOF + + +if test -z "$CFLAGS"; then + CF="$DEFINES $DEBUG -funroll-loops -fomit-frame-pointer $PLATFORM_CFLAGS" + echo >> global_config "CFLAGS = $CF $OPTIMIZE" + if test -z "$LESS_OPT"; then + echo >> global_config "CFLAGS_lessopt = $CF $OPTIMIZE_less" + else + echo >> global_config "CFLAGS_lessopt = $CF $OPTIMIZE_less" + fi +fi + +cat >> global_config << EOF +CC = ${CROSS}$CC +AR = ${CROSS}ar +NASM = nasm +EOF + +if [ ${USE_CSS} = 1 ]; then +cat >> global_config << EOF +CFLAGS += -DHAVE_CSS +EOF +fi + +if [ ${USE_MMX} = 1 ]; then +cat >> global_config << EOF +CFLAGS += -DHAVE_MMX +MMXOBJS = \ + video/mmxidct.o \ + video/reconmmx.o +MMXOBJS2 = \ + mmxidct.o \ + reconmmx.o +EOF +fi + + + + +echo "done" diff --git a/core/multimedia/opieplayer/libmpeg3/docs/index.html b/core/multimedia/opieplayer/libmpeg3/docs/index.html new file mode 100644 index 0000000..2d79978 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/docs/index.html @@ -0,0 +1,306 @@ +LibMPEG3 + +
+Using LibMPEG3 to make your own MPEG applications

+ + + + + +
+ +Author: Adam Williams broadcast@earthling.net
+Homepage: heroinewarrior.com
+
+
+

+ +

+ + +LibMPEG3 decodes the many many derivatives of MPEG standards into +uncompressed data suitable for editing and playback.

+ +libmpeg3 currently decodes:

+ +

MPEG-2 video
+MPEG-1 video
+mp3 audio
+mp2 audio
+ac3 audio
+MPEG-2 system streams
+MPEG-1 system streams +

+ +The video output can be in many different color models and frame +sizes. The audio output can be in twos compliment or floating +point.

+ + + + + + + + + +STEP 1: Verifying file compatibility

+ +Programs using libmpeg3 must #include "libmpeg3.h".

+ +Call mpeg3_check_sig to verify if the file can be read by +libmpeg3. This returns a 1 if it is compatible and 0 if it isn't.

+ + + + + + + + + + + +STEP 2: Open the file

+ +You need an mpeg3_t* file descriptor:

+ +mpeg3_t* file; + +

+ +Then you need to open the file:

+ +file = mpeg3_open(char *path);

+ +mpeg3_open returns a NULL if the file couldn't be opened +for some reason. Be sure to check this. Everything you do with +libmpeg3 requires passing the file pointer.

+ + + + + + + + + + + + + + +STEP 3: How many CPUs do you want to use?

+ +Call mpeg3_set_cpus(mpeg3_t *file, int cpus) to set how +many CPUs should be devoted to video decompression. LibMPEG3 can use +any number. If you don't call this right after opening the file, the +CPU number defaults to 1.

+ + + + + + + +STEP 4: Get some information about the file.

+ +There are a number of queries for the audio components of the stream:

+ +

+int mpeg3_has_audio(mpeg3_t *file);
+int mpeg3_total_astreams(mpeg3_t *file);             // Number of multiplexed audio streams
+int mpeg3_audio_channels(mpeg3_t *file, int stream);
+int mpeg3_sample_rate(mpeg3_t *file, int stream);
+long mpeg3_audio_samples(mpeg3_t *file, int stream); // Total length
+
+ +The audio is presented as a number of streams starting at 0 and +including mpeg3_total_astreams - 1. Each stream contains a +certain number of channels starting at 0 and including +mpeg3_audio_channels - 1. + +The methodology is first determine if the file has audio, then get +the number of streams in the file, then for each stream get the number +of channels, sample rate, and length.

+ +There are also queries for the video components:

+ +

+int mpeg3_has_video(mpeg3_t *file);
+int mpeg3_total_vstreams(mpeg3_t *file);            // Number of multiplexed video streams
+int mpeg3_video_width(mpeg3_t *file, int stream);
+int mpeg3_video_height(mpeg3_t *file, int stream);
+float mpeg3_frame_rate(mpeg3_t *file, int stream);  // Frames/sec
+long mpeg3_video_frames(mpeg3_t *file, int stream); // Total length
+
+ +The video behavior is the same as with audio, except that video has no +subdivision under streams. Frame rate is a floating point +number of frames per second.

+ + + + + + + +STEP 5: Seeking to a point in the file

+ +Each audio stream and each video stream has a position in the file +independant of each other stream. A variety of methods are available +for specifying the position of a stream: percentage, frame, sample. +Which method you use depends on whether you're seeking audio or video +and whether you're seeking all tracks to a percentage of the file.

+ +The preferred seeking method if you're writing a player is:

+ +

+int mpeg3_seek_percentage(mpeg3_t *file, double percentage);
+double mpeg3_tell_percentage(mpeg3_t *file);
+
+ +This seeks all tracks to a percentage of the file length. The +percentage is from 0 to 1.

+ +The alternative is absolute seeking. The audio seeking is handled +by:

+ +

+int mpeg3_set_sample(mpeg3_t *file, long sample, int stream);    // Seek
+long mpeg3_get_sample(mpeg3_t *file, int stream);    // Tell current position
+
+ +and the video seeking is handled by:

+ +

+int mpeg3_set_frame(mpeg3_t *file, long frame, int stream); // Seek
+long mpeg3_get_frame(mpeg3_t *file, int stream);            // Tell current position
+
+ + +You can either perform percentage seeking or absolute seeking but not +both on the same file handle. Once you perform either method, the file +becomes configured for that method.

+ +If you're in percentage seeking mode and you want the current time +stamp in the file you can't use mpeg3_tell_percentage because you don't +know how many seconds the total length is. The +mpeg3_audio_samples and mpeg3_video_frames +commands don't work in percentage seeking. Instead use + +

+double mpeg3_get_time(mpeg3_t *file);
+
+ +which gives you the last timecode read in seconds. The MPEG standard +specifies timecodes being placed in the streams.

+ + + + + + + + + + + +STEP 6: Read the data

+ +To read audio data use:

+ +

+int mpeg3_read_audio(mpeg3_t *file, 
+		float *output_f,      // Pointer to pre-allocated buffer of floats
+		short *output_i,      // Pointer to pre-allocated buffer if int16's
+		int channel,          // Channel to decode
+		long samples,         // Number of samples to decode
+		int stream);          // Stream containing the channel
+
+ +This decodes a buffer of sequential floats or int16's for a single +channel, depending on which *output... parameter has a nonzero +argument. To get a floating point buffer pass a pre-allocated buffer +to output_f and NULL to output_i. To get an +int16 buffer pass NULL to output_f and a pre-allocated +buffer to output_i.

+ +After reading an audio buffer, the current position in the one stream +is advanced. How then, do you read more than one channel of audio +data? Use + +

+mpeg3_reread_audio(mpeg3_t *file, 
+		float *output_f,      /* Pointer to pre-allocated buffer of floats */
+		short *output_i,      /* Pointer to pre-allocated buffer of int16's */
+		int channel,          /* Channel to decode */
+		long samples,         /* Number of samples to decode */
+		int stream);
+
+ +to read each remaining channel after the first channel.

+ +To read video data there are two methods. RGB frames or YUV +frames. To get an RGB frame use:
+ +

+int mpeg3_read_frame(mpeg3_t *file, 
+		unsigned char **output_rows, // Array of pointers to the start of each output row
+		int in_x,                    // Location in input frame to take picture
+		int in_y, 
+		int in_w, 
+		int in_h, 
+		int out_w,                   // Dimensions of output_rows
+		int out_h, 
+		int color_model,             // One of the color model #defines given above.
+		int stream);
+
+ +The video decoding works like a camcorder taking copy of a movie +screen. The decoder "sees" a region of the movie screen defined by +in_x, in_y, in_w, in_h and transfers it to the frame +buffer defined by **output_rows. The input values must be +within the boundaries given by mpeg3_video_width and +mpeg3_video_height. The size of the frame buffer is +defined by out_w, out_h. Although the input dimensions +are constrained, the frame buffer can be any size.

+ +color_model defines which RGB color model the picture +should be decoded to and the possible values are given in +libmpeg3.h. The frame buffer pointed to by +output_rows must have enough memory allocated to store the +color model you select.

+ +You must allocate 4 extra bytes in the last output_row. This is +scratch area for the MMX routines.

+ +mpeg3_read_frame advances the position in the one stream by 1 frame.

+ +The alternative is YUV frames:
+ +

+int mpeg3_read_yuvframe(mpeg3_t *file,
+		char *y_output,
+		char *u_output,
+		char *v_output,
+		int in_x,
+		int in_y,
+		int in_w,
+		int in_h,
+		int stream);
+
+ +The behavior of in_x, in_y, in_w, in_h is identical to mpeg3_read_frame +except here you have no control over the output frame size. You +must allocate in_w * in_h for the y_output, and in_w * in_h / 4 for the +chroma outputs.

+ + + + + +STEP 7: Close the file

+ +Be sure to close the file with mpeg3_close(mpeg3_t *file) +when you're done with it. diff --git a/core/multimedia/opieplayer/libmpeg3/dump.c b/core/multimedia/opieplayer/libmpeg3/dump.c new file mode 100644 index 0000000..7158712 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/dump.c @@ -0,0 +1,79 @@ +#include "libmpeg3.h" +#include + +#define BUFSIZE 4096 + +int main(int argc, char *argv[]) +{ + mpeg3_t *file; + int i, result = 0; + unsigned char *output, **output_rows; + float *audio_output_f; + short *audio_output_i; + long total_samples = 0; + + if(argc < 2) + { + printf("Need an MPEG stream.\n"); + exit(1); + } + + file = mpeg3_open(argv[1]); + if(file) + { + fprintf(stderr, "MMX supported %d\n", file->have_mmx); + fprintf(stderr, "Audio streams: %d\n", mpeg3_total_astreams(file)); + for(i = 0; i < mpeg3_total_astreams(file); i++) + { + fprintf(stderr, " Stream %d: channels %d sample rate %d total samples %ld\n", + i, + mpeg3_audio_channels(file, i), + mpeg3_sample_rate(file, i), + mpeg3_audio_samples(file, i)); + } + fprintf(stderr, "Video streams: %d\n", mpeg3_total_vstreams(file)); + for(i = 0; i < mpeg3_total_vstreams(file); i++) + { + fprintf(stderr, " Stream %d: width %d height %d frame rate %0.3f total frames %ld\n", + i, + mpeg3_video_width(file, i), + mpeg3_video_height(file, i), + mpeg3_frame_rate(file, i), + mpeg3_video_frames(file, i)); + } +fprintf(stderr,"S"); + + mpeg3_set_cpus(file, 1); +fprintf(stderr,"s"); +/* audio_output_f = malloc(BUFSIZE * sizeof(float)); */ + audio_output_i = (short*)malloc(BUFSIZE * 2 * sizeof(short)); +fprintf(stderr,"x"); +/* mpeg3_set_sample(file, 11229518, 0); */ + /*result = mpeg3_read_audio(file, audio_output_f, 0, 0, BUFSIZE, 0);*/ + for (i=0; i<100; i++) { +fprintf(stderr,"c"); + result = mpeg3_read_audio(file, 0, audio_output_i, 0, BUFSIZE, 0); +fprintf(stderr,"read\n"); + } + //fwrite(audio_output_i, BUFSIZE, 1, stdout); + + output = (unsigned char*)malloc(mpeg3_video_width(file, 0) * mpeg3_video_height(file, 0) * 3 + 4); + output_rows = (unsigned char**)malloc(sizeof(unsigned char*) * mpeg3_video_height(file, 0)); + for(i = 0; i < mpeg3_video_height(file, 0); i++) + output_rows[i] = &output[i * mpeg3_video_width(file, 0) * 3]; +// mpeg3_set_frame(file, 1000, 0); + result = mpeg3_read_frame(file, + output_rows, + 0, + 0, + mpeg3_video_width(file, 0), + mpeg3_video_height(file, 0), + mpeg3_video_width(file, 0), + mpeg3_video_height(file, 0), + MPEG3_RGB888, + 0); + + mpeg3_close(file); + } + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3.c b/core/multimedia/opieplayer/libmpeg3/libmpeg3.c new file mode 100644 index 0000000..c0fc570 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3.c @@ -0,0 +1,672 @@ +#include "libmpeg3.h" +#include "mpeg3protos.h" + +#include +#include + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +mpeg3_t* mpeg3_new(char *path) +{ + int i; + mpeg3_t *file = (mpeg3_t*)calloc(1, sizeof(mpeg3_t)); + file->cpus = 1; + file->fs = mpeg3_new_fs(path); + file->have_mmx = mpeg3_mmx_test(); + file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1); + return file; +} + +int mpeg3_delete(mpeg3_t *file) +{ + int i; + + for(i = 0; i < file->total_vstreams; i++) + mpeg3_delete_vtrack(file, file->vtrack[i]); + + for(i = 0; i < file->total_astreams; i++) + mpeg3_delete_atrack(file, file->atrack[i]); + + mpeg3_delete_fs(file->fs); + mpeg3_delete_demuxer(file->demuxer); + free(file); +} + +int mpeg3_check_sig(char *path) +{ + mpeg3_fs_t *fs; + unsigned int bits; + char *ext; + int result = 0; + + fs = mpeg3_new_fs(path); + if(mpeg3io_open_file(fs)) + { +/* File not found */ + return 0; + } + + bits = mpeg3io_read_int32(fs); +/* Test header */ + if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) + { + result = 1; + } + else + if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) || + (bits == MPEG3_PACK_START_CODE) || + ((bits & 0xfff00000) == 0xfff00000) || + (bits == MPEG3_SEQUENCE_START_CODE) || + (bits == MPEG3_PICTURE_START_CODE) || + (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) || + ((bits >> 8) == MPEG3_ID3_PREFIX) || + (bits == MPEG3_RIFF_CODE)) + { + result = 1; + + ext = strrchr(path, '.'); + if(ext) + { +/* Test file extension. */ + if(strncasecmp(ext, ".mp2", 4) && + strncasecmp(ext, ".mp3", 4) && + strncasecmp(ext, ".m1v", 4) && + strncasecmp(ext, ".m2v", 4) && + strncasecmp(ext, ".m2s", 4) && + strncasecmp(ext, ".mpg", 4) && + strncasecmp(ext, ".vob", 4) && + strncasecmp(ext, ".mpeg", 4) && + strncasecmp(ext, ".ac3", 4)) + result = 0; + } + } + + mpeg3io_close_file(fs); + mpeg3_delete_fs(fs); + return result; +} + +mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file) +{ + mpeg3_t *file = 0; + unsigned int bits; + int i, done; + +/* Initialize the file structure */ + file = mpeg3_new(path); + +/* Need to perform authentication before reading a single byte. */ + if(mpeg3io_open_file(file->fs)) + { + mpeg3_delete(file); + return 0; + } + +/* =============================== Create the title objects ========================= */ + bits = mpeg3io_read_int32(file->fs); + + if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) /* TOCV */ + { +/* Table of contents for another file */ + if(mpeg3_read_toc(file)) + { + mpeg3_delete(file); + return 0; + } + mpeg3io_close_file(file->fs); + } + else + if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) + { +/* Transport stream */ + file->packet_size = MPEG3_TS_PACKET_SIZE; + file->is_transport_stream = 1; + } + else + if(bits == MPEG3_PACK_START_CODE) + { +/* Program stream */ + file->packet_size = MPEG3_DVD_PACKET_SIZE; + file->is_program_stream = 1; + } + else + if((bits & 0xfff00000) == 0xfff00000 || + ((bits >> 8) == MPEG3_ID3_PREFIX) || + (bits == MPEG3_RIFF_CODE)) + { +/* MPEG Audio only */ + file->packet_size = MPEG3_DVD_PACKET_SIZE; + file->has_audio = 1; + file->is_audio_stream = 1; + } + else + if(bits == MPEG3_SEQUENCE_START_CODE || + bits == MPEG3_PICTURE_START_CODE) + { +/* Video only */ + file->packet_size = MPEG3_DVD_PACKET_SIZE; + file->is_video_stream = 1; + } + else + if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) + { +/* AC3 Audio only */ + file->packet_size = MPEG3_DVD_PACKET_SIZE; + file->has_audio = 1; + file->is_audio_stream = 1; + } + else + { +/* file->packet_size = MPEG3_DVD_PACKET_SIZE; */ +/* file->is_audio_stream = 1; */ + mpeg3_delete(file); + fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n"); + return 0; + } + +/* Create title */ +/* Copy timecodes from an old demuxer */ + if(old_file && mpeg3_get_demuxer(old_file)) + { + mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file)); + } + else +/* Start from scratch */ + if(!file->demuxer->total_titles) + { + mpeg3demux_create_title(file->demuxer, 0, 0); + } + +/* =============================== Get title information ========================= */ + if(file->is_transport_stream || file->is_program_stream) + { +/* Create video tracks */ +/* Video must be created before audio because audio uses the video timecode */ +/* to get its length. */ + for(i = 0; i < MPEG3_MAX_STREAMS; i++) + { + if(file->demuxer->vstream_table[i]) + { + file->vtrack[file->total_vstreams] = mpeg3_new_vtrack(file, i, file->demuxer); + if(file->vtrack[file->total_vstreams]) file->total_vstreams++; + } + } + +/* Create audio tracks */ + for(i = 0; i < MPEG3_MAX_STREAMS; i++) + { + if(file->demuxer->astream_table[i]) + { + file->atrack[file->total_astreams] = mpeg3_new_atrack(file, + i, + file->demuxer->astream_table[i], + file->demuxer); + if(file->atrack[file->total_astreams]) file->total_astreams++; + } + } + } + else + if(file->is_video_stream) + { +/* Create video tracks */ + file->vtrack[0] = mpeg3_new_vtrack(file, -1, file->demuxer); + if(file->vtrack[0]) file->total_vstreams++; + } + else + if(file->is_audio_stream) + { +/* Create audio tracks */ + file->atrack[0] = mpeg3_new_atrack(file, -1, AUDIO_UNKNOWN, file->demuxer); + if(file->atrack[0]) file->total_astreams++; + } + + if(file->total_vstreams) file->has_video = 1; + if(file->total_astreams) file->has_audio = 1; + + mpeg3io_close_file(file->fs); + return file; +} + +mpeg3_t* mpeg3_open(char *path) +{ + return mpeg3_open_copy(path, 0); +} + +int mpeg3_close(mpeg3_t *file) +{ +/* File is closed in the same procedure it is opened in. */ + mpeg3_delete(file); + return 0; +} + +int mpeg3_set_cpus(mpeg3_t *file, int cpus) +{ + int i; + file->cpus = cpus; + for(i = 0; i < file->total_vstreams; i++) + mpeg3video_set_cpus(file->vtrack[i]->video, cpus); + return 0; +} + +int mpeg3_set_mmx(mpeg3_t *file, int use_mmx) +{ + int i; + file->have_mmx = use_mmx; + for(i = 0; i < file->total_vstreams; i++) + mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx); + return 0; +} + +int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams) +{ + mpeg3_t *file = mpeg3_open(path); + mpeg3_demuxer_t *demuxer; + int i; + + if(file) + { + fprintf(output, "TOCVERSION 2\n" + "PATH: %s\n", path); + demuxer = mpeg3_new_demuxer(file, 0, 0, -1); + mpeg3demux_create_title(demuxer, timecode_search, output); +/* Just print the first title's streams */ + if(print_streams) mpeg3demux_print_streams(demuxer, output); + + fprintf(output, "SIZE: %ld\n", demuxer->titles[demuxer->current_title]->total_bytes); + fprintf(output, "PACKETSIZE: %ld\n", demuxer->packet_size); + + mpeg3demux_print_timecodes(demuxer->titles[demuxer->current_title], output); + + mpeg3_delete_demuxer(demuxer); + mpeg3_close(file); + return 0; + } + return 1; +} + +int mpeg3_read_toc(mpeg3_t *file) +{ + char string[MPEG3_STRLEN]; + int number1; + +/* Test version number */ + file->is_program_stream = 1; + mpeg3io_seek(file->fs, 0); + fscanf(file->fs->fd, "%s %d", string, &number1); + if(number1 > 2 || number1 < 2) return 1; + +/* Read titles */ + mpeg3demux_read_titles(file->demuxer); + return 0; +} + +int mpeg3_has_audio(mpeg3_t *file) +{ + return file->has_audio; +} + +int mpeg3_total_astreams(mpeg3_t *file) +{ + return file->total_astreams; +} + +int mpeg3_audio_channels(mpeg3_t *file, + int stream) +{ + if(file->has_audio) + return file->atrack[stream]->channels; + return -1; +} + +int mpeg3_sample_rate(mpeg3_t *file, + int stream) +{ + if(file->has_audio) + return file->atrack[stream]->sample_rate; + return -1; +} + +long mpeg3_get_sample(mpeg3_t *file, + int stream) +{ + if(file->has_audio) + return file->atrack[stream]->current_position; + return -1; +} + +int mpeg3_set_sample(mpeg3_t *file, + long sample, + int stream) +{ + if(file->has_audio) + { + file->atrack[stream]->current_position = sample; + mpeg3audio_seek_sample(file->atrack[stream]->audio, sample); + return 0; + } + return -1; +} + +long mpeg3_audio_samples(mpeg3_t *file, + int stream) +{ + if(file->has_audio) + return file->atrack[stream]->total_samples; + return -1; +} + +int mpeg3_has_video(mpeg3_t *file) +{ + return file->has_video; +} + +int mpeg3_total_vstreams(mpeg3_t *file) +{ + return file->total_vstreams; +} + +int mpeg3_video_width(mpeg3_t *file, + int stream) +{ + if(file->has_video) + return file->vtrack[stream]->width; + return -1; +} + +int mpeg3_video_height(mpeg3_t *file, + int stream) +{ + if(file->has_video) + return file->vtrack[stream]->height; + return -1; +} + +float mpeg3_frame_rate(mpeg3_t *file, + int stream) +{ + if(file->has_video) + return file->vtrack[stream]->frame_rate; + return -1; +} + +long mpeg3_video_frames(mpeg3_t *file, + int stream) +{ + if(file->has_video) + return file->vtrack[stream]->total_frames; + return -1; +} + +long mpeg3_get_frame(mpeg3_t *file, + int stream) +{ + if(file->has_video) + return file->vtrack[stream]->current_position; + return -1; +} + +int mpeg3_set_frame(mpeg3_t *file, + long frame, + int stream) +{ + if(file->has_video) + { + file->vtrack[stream]->current_position = frame; + mpeg3video_seek_frame(file->vtrack[stream]->video, frame); + return 0; + } + return -1; +} + +int mpeg3_seek_percentage(mpeg3_t *file, double percentage) +{ + int i; + for(i = 0; i < file->total_astreams; i++) + { + mpeg3audio_seek_percentage(file->atrack[i]->audio, percentage); + } + + for(i = 0; i < file->total_vstreams; i++) + { + mpeg3video_seek_percentage(file->vtrack[i]->video, percentage); + } + return 0; +} + +int mpeg3_previous_frame(mpeg3_t *file, int stream) +{ + file->last_type_read = 2; + file->last_stream_read = stream; + + if(file->has_video) + return mpeg3video_previous_frame(file->vtrack[stream]->video); +} + +double mpeg3_tell_percentage(mpeg3_t *file) +{ + double percent = 0; + if(file->last_type_read == 1) + { + percent = mpeg3demux_tell_percentage(file->atrack[file->last_stream_read]->demuxer); + } + + if(file->last_type_read == 2) + { + percent = mpeg3demux_tell_percentage(file->vtrack[file->last_stream_read]->demuxer); + } + return percent; +} + +double mpeg3_get_time(mpeg3_t *file) +{ + double atime = 0, vtime = 0; + + if(file->is_transport_stream || file->is_program_stream) + { +/* Timecode only available in transport stream */ + if(file->last_type_read == 1) + { + atime = mpeg3demux_get_time(file->atrack[file->last_stream_read]->demuxer); + } + else + if(file->last_type_read == 2) + { + vtime = mpeg3demux_get_time(file->vtrack[file->last_stream_read]->demuxer); + } + } + else + { +/* Use percentage and total time */ + if(file->has_audio) + { + atime = mpeg3demux_tell_percentage(file->atrack[0]->demuxer) * + mpeg3_audio_samples(file, 0) / mpeg3_sample_rate(file, 0); + } + + if(file->has_video) + { + vtime = mpeg3demux_tell_percentage(file->vtrack[0]->demuxer) * + mpeg3_video_frames(file, 0) / mpeg3_frame_rate(file, 0); + } + } + + return MAX(atime, vtime); +} + +int mpeg3_end_of_audio(mpeg3_t *file, int stream) +{ + int result = 0; + result = mpeg3demux_eof(file->atrack[stream]->demuxer); + return result; +} + +int mpeg3_end_of_video(mpeg3_t *file, int stream) +{ + int result = 0; + result = mpeg3demux_eof(file->vtrack[stream]->demuxer); + return result; +} + + +int mpeg3_read_frame(mpeg3_t *file, + unsigned char **output_rows, + int in_x, + int in_y, + int in_w, + int in_h, + int out_w, + int out_h, + int color_model, + int stream) +{ + int result = -1; + + if(file->has_video) + { + result = mpeg3video_read_frame(file->vtrack[stream]->video, + file->vtrack[stream]->current_position, + output_rows, + in_x, + in_y, + in_w, + in_h, + out_w, + out_h, + color_model); + file->last_type_read = 2; + file->last_stream_read = stream; + file->vtrack[stream]->current_position++; + } + return result; +} + +int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream) +{ + int result = -1; + + if(file->has_video) + { + result = mpeg3video_drop_frames(file->vtrack[stream]->video, + frames); + if(frames > 0) file->vtrack[stream]->current_position += frames; + file->last_type_read = 2; + file->last_stream_read = stream; + } + return result; +} + +int mpeg3_read_yuvframe(mpeg3_t *file, + char *y_output, + char *u_output, + char *v_output, + int in_x, + int in_y, + int in_w, + int in_h, + int stream) +{ + int result = -1; + +//printf("mpeg3_read_yuvframe 1 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer)); + if(file->has_video) + { + result = mpeg3video_read_yuvframe(file->vtrack[stream]->video, + file->vtrack[stream]->current_position, + y_output, + u_output, + v_output, + in_x, + in_y, + in_w, + in_h); + file->last_type_read = 2; + file->last_stream_read = stream; + file->vtrack[stream]->current_position++; + } +//printf("mpeg3_read_yuvframe 2 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer)); + return result; +} + + +int mpeg3_read_audio(mpeg3_t *file, + mpeg3_real_t *output_f, + short *output_i, int sampleSpacing, + int channel, + long samples, + int stream) +{ + int result = -1; + +//printf("mpeg3_read_audio 1 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer)); + if(file->has_audio) + { + result = mpeg3audio_decode_audio(file->atrack[stream]->audio, + output_f, + output_i, sampleSpacing, + channel, + file->atrack[stream]->current_position, + samples); + file->last_type_read = 1; + file->last_stream_read = stream; + file->atrack[stream]->current_position += samples; + } +//printf("mpeg3_read_audio 2 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer)); + + return result; +} + +int mpeg3_reread_audio(mpeg3_t *file, + mpeg3_real_t *output_f, + short *output_i, int sampleSpacing, + int channel, + long samples, + int stream) +{ + if(file->has_audio) + { + mpeg3_set_sample(file, + file->atrack[stream]->current_position - samples, + stream); + file->last_type_read = 1; + file->last_stream_read = stream; + return mpeg3_read_audio(file, + output_f, + output_i, sampleSpacing, + channel, + samples, + stream); + } + return -1; +} + +int mpeg3_read_audio_chunk(mpeg3_t *file, + unsigned char *output, + long *size, + long max_size, + int stream) +{ + int result = 0; + if(file->has_audio) + { + result = mpeg3audio_read_raw(file->atrack[stream]->audio, output, size, max_size); + file->last_type_read = 1; + file->last_stream_read = stream; + } + return result; +} + +int mpeg3_read_video_chunk(mpeg3_t *file, + unsigned char *output, + long *size, + long max_size, + int stream) +{ + int result = 0; + if(file->has_video) + { + result = mpeg3video_read_raw(file->vtrack[stream]->video, output, size, max_size); + file->last_type_read = 2; + file->last_stream_read = stream; + } + return result; +} diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3.h b/core/multimedia/opieplayer/libmpeg3/libmpeg3.h new file mode 100644 index 0000000..f4eced4 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3.h @@ -0,0 +1,175 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LIBMPEG3_H +#define LIBMPEG3_H + +#include "mpeg3private.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Supported color models for mpeg3_read_frame */ +#define MPEG3_RGB565 2 +#define MPEG3_BGR888 0 +#define MPEG3_BGRA8888 1 +#define MPEG3_RGB888 3 +#define MPEG3_RGBA8888 4 +#define MPEG3_RGBA16161616 5 + +/* Color models for the 601 to RGB conversion */ +/* 601 not implemented for scalar code */ +#define MPEG3_601_RGB565 11 +#define MPEG3_601_BGR888 7 +#define MPEG3_601_BGRA8888 8 +#define MPEG3_601_RGB888 9 +#define MPEG3_601_RGBA8888 10 + +/* Check for file compatibility. Return 1 if compatible. */ +LIBMPEG_EXPORT int mpeg3_check_sig(char *path); + +/* Open the MPEG3 stream. */ +LIBMPEG_EXPORT mpeg3_t* mpeg3_open(char *path); + +/* Open the MPEG3 stream and copy the tables from an already open stream. */ +/* Eliminates the initial timecode search. */ +LIBMPEG_EXPORT mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file); +LIBMPEG_EXPORT int mpeg3_close(mpeg3_t *file); + +/* Performance */ +LIBMPEG_EXPORT int mpeg3_set_cpus(mpeg3_t *file, int cpus); +LIBMPEG_EXPORT int mpeg3_set_mmx(mpeg3_t *file, int use_mmx); + +/* Query the MPEG3 stream about audio. */ +LIBMPEG_EXPORT int mpeg3_has_audio(mpeg3_t *file); +LIBMPEG_EXPORT int mpeg3_total_astreams(mpeg3_t *file); /* Number of multiplexed audio streams */ +LIBMPEG_EXPORT int mpeg3_audio_channels(mpeg3_t *file, int stream); +LIBMPEG_EXPORT int mpeg3_sample_rate(mpeg3_t *file, int stream); + +/* Total length obtained from the timecode. */ +/* For DVD files, this is unreliable. */ +LIBMPEG_EXPORT long mpeg3_audio_samples(mpeg3_t *file, int stream); +LIBMPEG_EXPORT int mpeg3_set_sample(mpeg3_t *file, long sample, int stream); /* Seek to a sample */ +LIBMPEG_EXPORT long mpeg3_get_sample(mpeg3_t *file, int stream); /* Tell current position */ + +/* Read a PCM buffer of audio from 1 channel and advance the position. */ +/* Return a 1 if error. */ +/* Stream defines the number of the multiplexed stream to read. */ +LIBMPEG_EXPORT int mpeg3_read_audio(mpeg3_t *file, + mpeg3_real_t *output_f, /* Pointer to pre-allocated buffer of floats */ + short *output_i, /* Pointer to pre-allocated buffer of int16's */ + int sampleSpacing, // how many bytes to skip over inbetween samples + int channel, /* Channel to decode */ + long samples, /* Number of samples to decode */ + int stream); /* Stream containing the channel */ + +/* Reread the last PCM buffer from a different channel and advance the position */ +LIBMPEG_EXPORT int mpeg3_reread_audio(mpeg3_t *file, + mpeg3_real_t *output_f, /* Pointer to pre-allocated buffer of floats */ + short *output_i, /* Pointer to pre-allocated buffer of int16's */ + int sampleSpacing, // how many bytes to skip over inbetween samples + int channel, /* Channel to decode */ + long samples, /* Number of samples to decode */ + int stream); /* Stream containing the channel */ + +/* Read the next compressed audio chunk. Store the size in size and return a */ +/* 1 if error. */ +/* Stream defines the number of the multiplexed stream to read. */ +LIBMPEG_EXPORT int mpeg3_read_audio_chunk(mpeg3_t *file, + unsigned char *output, + long *size, + long max_size, + int stream); + +/* Query the stream about video. */ +LIBMPEG_EXPORT int mpeg3_has_video(mpeg3_t *file); +LIBMPEG_EXPORT int mpeg3_total_vstreams(mpeg3_t *file); /* Number of multiplexed video streams */ +LIBMPEG_EXPORT int mpeg3_video_width(mpeg3_t *file, int stream); +LIBMPEG_EXPORT int mpeg3_video_height(mpeg3_t *file, int stream); +LIBMPEG_EXPORT float mpeg3_frame_rate(mpeg3_t *file, int stream); /* Frames/sec */ + +/* Total length. */ +/* For DVD files, this is 1 indicating only percentage seeking is available. */ +LIBMPEG_EXPORT long mpeg3_video_frames(mpeg3_t *file, int stream); +LIBMPEG_EXPORT int mpeg3_set_frame(mpeg3_t *file, long frame, int stream); /* Seek to a frame */ +LIBMPEG_EXPORT int mpeg3_skip_frames(); +LIBMPEG_EXPORT long mpeg3_get_frame(mpeg3_t *file, int stream); /* Tell current position */ + +/* Seek all the tracks based on a percentage of the total bytes in the */ +/* file or the total */ +/* time in a toc if one exists. Percentage is a 0 to 1 double. */ +/* This eliminates the need for tocs and 64 bit longs but doesn't */ +/* give frame accuracy. */ +LIBMPEG_EXPORT int mpeg3_seek_percentage(mpeg3_t *file, double percentage); +LIBMPEG_EXPORT double mpeg3_tell_percentage(mpeg3_t *file); +LIBMPEG_EXPORT int mpeg3_previous_frame(mpeg3_t *file, int stream); +LIBMPEG_EXPORT int mpeg3_end_of_audio(mpeg3_t *file, int stream); +LIBMPEG_EXPORT int mpeg3_end_of_video(mpeg3_t *file, int stream); + +/* Give the seconds time in the last packet read */ +LIBMPEG_EXPORT double mpeg3_get_time(mpeg3_t *file); + +/* Read a frame. The dimensions of the input area and output frame must be supplied. */ +/* The frame is taken from the input area and scaled to fit the output frame in 1 step. */ +/* Stream defines the number of the multiplexed stream to read. */ +/* The last row of **output_rows must contain 4 extra bytes for scratch work. */ +LIBMPEG_EXPORT int mpeg3_read_frame(mpeg3_t *file, + unsigned char **output_rows, /* Array of pointers to the start of each output row */ + int in_x, /* Location in input frame to take picture */ + int in_y, + int in_w, + int in_h, + int out_w, /* Dimensions of output_rows */ + int out_h, + int color_model, /* One of the color model #defines */ + int stream); + +/* Read a YUV frame. The 3 planes are copied into the y, u, and v buffers provided. */ +/* The input is cropped to the dimensions given but not scaled. */ +LIBMPEG_EXPORT int mpeg3_read_yuvframe(mpeg3_t *file, + char *y_output, + char *u_output, + char *v_output, + int in_x, + int in_y, + int in_w, + int in_h, + int stream); + +LIBMPEG_EXPORT int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream); + +/* Read the next compressed frame including headers. */ +/* Store the size in size and return a 1 if error. */ +/* Stream defines the number of the multiplexed stream to read. */ +LIBMPEG_EXPORT int mpeg3_read_video_chunk(mpeg3_t *file, + unsigned char *output, + long *size, + long max_size, + int stream); + +/* Master control */ +LIBMPEG_EXPORT int mpeg3_total_programs(); +LIBMPEG_EXPORT int mpeg3_set_program(int program); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3.pro b/core/multimedia/opieplayer/libmpeg3/libmpeg3.pro new file mode 100644 index 0000000..e2c35d3 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3.pro @@ -0,0 +1,42 @@ +TEMPLATE = lib +CONFIG += qt warn_on release +HEADERS = libmpeg3plugin.h libmpeg3pluginimpl.h +SOURCES = libmpeg3plugin.cpp libmpeg3pluginimpl.cpp \ + bitstream.c \ + libmpeg3.c \ + mpeg3atrack.c \ + mpeg3css.c \ + mpeg3demux.c \ + mpeg3io.c \ + mpeg3title.c \ + mpeg3vtrack.c \ + audio/ac3.c \ + audio/bit_allocation.c \ + audio/dct.c \ + audio/exponents.c \ + audio/header.c \ + audio/layer2.c \ + audio/layer3.c \ + audio/mantissa.c \ + audio/mpeg3audio.c \ + audio/pcm.c \ + audio/synthesizers.c \ + audio/tables.c \ + video/getpicture.c \ + video/headers.c \ + video/idct.c \ + video/macroblocks.c \ + video/mmxtest.c \ + video/motion.c \ + video/mpeg3video.c \ + video/output.c \ + video/reconstruct.c \ + video/seek.c \ + video/slice.c \ + video/vlc.c +TARGET = mpeg3plugin +DESTDIR = ../../plugins/codecs +INCLUDEPATH += $(QPEDIR)/include .. +DEPENDPATH += ../$(QPEDIR)/include .. +LIBS += -lqpe -lpthread -lm +VERSION = 1.0.0 diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.cpp b/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.cpp new file mode 100644 index 0000000..044cb4a --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.cpp @@ -0,0 +1,105 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "libmpeg3plugin.h" + +/* +bool LibMpeg3Plugin::audioReadSamples( short *output, int channel, long samples, int stream ) { + return file ? mpeg3_read_audio( file, 0, output, 0, channel, samples, stream ) == 1 : FALSE; +} + + +bool LibMpeg3Plugin::audioReReadSamples( short *output, int channel, long samples, int stream ) { + return file ? mpeg3_reread_audio( file, 0, output, 0, channel, samples, stream ) == 1 : FALSE; +} + + +bool LibMpeg3Plugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) { + samplesRead = samples; + return file ? mpeg3_read_audio( file, 0, output, 0, 0, samples, stream ) == 1 : FALSE; +} + + +bool LibMpeg3Plugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) { + bool err = FALSE; + if ( file ) { +#if 1 + err = mpeg3_read_audio ( file, 0, output, 1, 0, samples, stream ) == 1; + if ( err == FALSE ) { + err = mpeg3_reread_audio( file, 0, output + 1, 1, 1, samples, stream ) == 1; +#else + short left[samples]; + short right[samples]; + err = mpeg3_read_audio ( file, 0, left, 0, samples, stream ) == 1; + if ( !err ) + err = mpeg3_reread_audio( file, 0, right, 1, samples, stream ) == 1; + for ( int j = 0; j < samples; j++ ) { + output[j*2+0] = left[j]; + output[j*2+1] = right[j]; +#endif + } + } + samplesRead = samples; + return err; +} +*/ + +bool LibMpeg3Plugin::audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ) { + samplesRead = samples; + switch ( channels ) { + case 1: + return file ? mpeg3_read_audio( file, 0, output, 0, 0, samples, stream ) == 1 : FALSE; + case 2: + if ( ( file ) && ( mpeg3_read_audio( file, 0, output, 1, 0, samples, stream ) != 1 ) && + ( mpeg3_reread_audio( file, 0, output + 1, 1, 1, samples, stream ) != 1 ) ) + return TRUE; + return FALSE; + } + return FALSE; +} + +bool LibMpeg3Plugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) { + int format = MPEG3_RGB565; + switch ( color_model ) { + case RGB565: format = MPEG3_RGB565; break; + case BGR565: /*format = MPEG3_BGR565;*/ break; + case RGBA8888: format = MPEG3_RGBA8888; break; + case BGRA8888: format = MPEG3_BGRA8888; break; + } + return file ? mpeg3_read_frame( file, output_rows, in_x, in_y, in_w, in_h, in_w, in_h, format, stream ) == 1 : FALSE; +} + + +bool LibMpeg3Plugin::videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) { + int format = MPEG3_RGB565; + switch ( color_model ) { + case RGB565: format = MPEG3_RGB565; break; + case BGR565: /*format = MPEG3_BGR565;*/ break; + case RGBA8888: format = MPEG3_RGBA8888; break; + case BGRA8888: format = MPEG3_BGRA8888; break; + } + return file ? mpeg3_read_frame( file, output_rows, in_x, in_y, in_w, in_h, out_w, out_h, format, stream ) == 1 : FALSE; +} + + +bool LibMpeg3Plugin::videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) { + return file ? mpeg3_read_yuvframe( file, y_output, u_output, v_output, in_x, in_y, in_w, in_h, stream ) == 1 : FALSE; +} + + diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.h b/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.h new file mode 100644 index 0000000..0a06264 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.h @@ -0,0 +1,113 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LIBMPEG3_PLUGIN_H +#define LIBMPEG3_PLUGIN_H + + +#include +#include +#include "libmpeg3.h" +#include "mpeg3protos.h" +#include "mediaplayerplugininterface.h" + + +class LibMpeg3Plugin : public MediaPlayerDecoder { + +public: + LibMpeg3Plugin() { file = NULL; } + ~LibMpeg3Plugin() { close(); } + + const char *pluginName() { return "LibMpeg3Plugin"; } + const char *pluginComment() { return "This is the libmpeg3 library writen by ... which has been modified by trolltech to use fixed point maths"; } + double pluginVersion() { return 1.0; } + + bool isFileSupported( const QString& fileName ) { return mpeg3_check_sig( (char *)fileName.latin1() ) == 1; } + bool open( const QString& fileName ) { file = mpeg3_open( (char *)fileName.latin1() ); return file != NULL; } + bool close() { if ( file ) { int r = mpeg3_close( file ); file = NULL; return r == 1; } return FALSE; } + bool isOpen() { return file != NULL; } + const QString &fileInfo() { return strInfo = QString( "" ); } + + // If decoder doesn't support audio then return 0 here + int audioStreams() { return file ? mpeg3_total_astreams( file ) : 0; } + int audioChannels( int stream ) { return file ? mpeg3_audio_channels( file, stream ) : 0; } + int audioFrequency( int stream ) { return file ? mpeg3_sample_rate( file, stream ) : 0; } + int audioSamples( int stream ) { return file ? mpeg3_audio_samples( file, stream ) : 0; } + bool audioSetSample( long sample, int stream ) { return file ? mpeg3_set_sample( file, sample, stream) == 1 : FALSE; } + long audioGetSample( int stream ) { return file ? mpeg3_get_sample( file, stream ) : 0; } +// bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ); +// bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ); + bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ); +// bool audioReadSamples( short *output, int channel, long samples, int stream ); +// bool audioReReadSamples( short *output, int channel, long samples, int stream ); + + // If decoder doesn't support video then return 0 here + int videoStreams() { return file ? mpeg3_total_vstreams( file ) : 0; } + int videoWidth( int stream ) { return file ? mpeg3_video_width( file, stream ) : 0; } + int videoHeight( int stream ) { return file ? mpeg3_video_height( file, stream ) : 0; } + double videoFrameRate( int stream ) { return file ? mpeg3_frame_rate( file, stream ) : 0.0; } + int videoFrames( int stream ) +{ return file ? mpeg3_video_frames( file, stream ) : 0; } +/* +{ + if ( file ) { + int frames = mpeg3_video_frames( file, stream ); + if ( frames == 1 ) { + int res = mpeg3_seek_percentage( file, 0.99 ); + printf("res: %i\n", res ); + mpeg3video_seek( file->vtrack[stream]->video ); + frames = mpeg3_get_frame( file, stream ); + mpeg3_seek_percentage( file, 0.0 ); + } + return frames; + } + return 0; +} +*/ + bool videoSetFrame( long frame, int stream ) { return file ? mpeg3_set_frame( file, frame, stream) == 1 : FALSE; } + long videoGetFrame( int stream ) { return file ? mpeg3_get_frame( file, stream ) : 0; } + bool videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ); + bool videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ); + bool videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ); + + // Profiling + double getTime() { return file ? mpeg3_get_time( file ) : 0.0; } + + // Ignore if these aren't supported + bool setSMP( int cpus ) { return file ? mpeg3_set_cpus( file, cpus ) == 1 : FALSE; } + bool setMMX( bool useMMX ) { return file ? mpeg3_set_mmx( file, useMMX ) == 1 : FALSE; } + + // Capabilities + bool supportsAudio() { return TRUE; } + bool supportsVideo() { return TRUE; } + bool supportsYUV() { return TRUE; } + bool supportsMMX() { return TRUE; } + bool supportsSMP() { return TRUE; } + bool supportsStereo() { return TRUE; } + bool supportsScaling() { return TRUE; } + +private: + mpeg3_t *file; + QString strInfo; + +}; + + +#endif + diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.cpp b/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.cpp new file mode 100644 index 0000000..e7216af --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.cpp @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "libmpeg3plugin.h" +#include "libmpeg3pluginimpl.h" + + +LibMpeg3PluginImpl::LibMpeg3PluginImpl() + : libmpeg3plugin(0), ref(0) +{ +} + + +LibMpeg3PluginImpl::~LibMpeg3PluginImpl() +{ + if ( libmpeg3plugin ) + delete libmpeg3plugin; +} + + +MediaPlayerDecoder *LibMpeg3PluginImpl::decoder() +{ + if ( !libmpeg3plugin ) + libmpeg3plugin = new LibMpeg3Plugin; + return libmpeg3plugin; +} + + +MediaPlayerEncoder *LibMpeg3PluginImpl::encoder() +{ + return NULL; +} + + +#ifndef QT_NO_COMPONENT + + +QRESULT LibMpeg3PluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) ) + *iface = this, (*iface)->addRef(); + return QS_OK; +} + + +Q_EXPORT_INTERFACE() +{ + Q_CREATE_INSTANCE( LibMpeg3PluginImpl ) +} + + +#endif + diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.h b/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.h new file mode 100644 index 0000000..29ec6ba --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.h @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LIBMPEG3_PLUGIN_IMPL_H +#define LIBMPEG3_PLUGIN_IMPL_H + + +#include "../mediaplayerplugininterface.h" + + +class LibMpeg3Plugin; + + +class LibMpeg3PluginImpl : public MediaPlayerPluginInterface +{ +public: + LibMpeg3PluginImpl(); + virtual ~LibMpeg3PluginImpl(); + +#ifndef QT_NO_COMPONENT + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT + +#endif + + virtual MediaPlayerDecoder *decoder(); + virtual MediaPlayerEncoder *encoder(); + +private: + LibMpeg3Plugin *libmpeg3plugin; + ulong ref; +}; + + +#endif + diff --git a/core/multimedia/opieplayer/libmpeg3/make_package b/core/multimedia/opieplayer/libmpeg3/make_package new file mode 100755 index 0000000..4be86da --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/make_package @@ -0,0 +1,10 @@ +#!/bin/sh + +VERSION=1.2.1 + +rm -r /tmp/libmpeg3-$VERSION +mkdir -p /tmp/libmpeg3-$VERSION +make clean +cp -rd * /tmp/libmpeg3-$VERSION +cd /tmp +tar zcf libmpeg3-$VERSION.tar.gz libmpeg3-$VERSION diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.c b/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.c new file mode 100644 index 0000000..e1a900b --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.c @@ -0,0 +1,36 @@ +#include "libmpeg3.h" +#include "mpeg3protos.h" + +#include + +mpeg3_atrack_t* mpeg3_new_atrack(mpeg3_t *file, int stream_id, int format, mpeg3_demuxer_t *demuxer) +{ + mpeg3_atrack_t *new_atrack; + + new_atrack = (mpeg3_atrack_t*)calloc(1, sizeof(mpeg3_atrack_t)); + new_atrack->channels = 0; + new_atrack->sample_rate = 0; + new_atrack->total_samples = 0; + new_atrack->current_position = 0; + new_atrack->demuxer = mpeg3_new_demuxer(file, 1, 0, stream_id); + if(demuxer) mpeg3demux_copy_titles(new_atrack->demuxer, demuxer); + new_atrack->audio = mpeg3audio_new(file, new_atrack, format); + + if(!new_atrack->audio) + { +/* Failed */ + mpeg3_delete_atrack(file, new_atrack); + new_atrack = 0; + } + return new_atrack; +} + +int mpeg3_delete_atrack(mpeg3_t *file, mpeg3_atrack_t *atrack) +{ + if(atrack->audio) + mpeg3audio_delete(atrack->audio); + if(atrack->demuxer) + mpeg3_delete_demuxer(atrack->demuxer); + free(atrack); +} + diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.h b/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.h new file mode 100644 index 0000000..9d70640 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.h @@ -0,0 +1,36 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3ATRACK_H +#define MPEG3ATRACK_H + +#include "mpeg3demux.h" +#include "audio/mpeg3audio.h" + +struct mpeg3_atrack_rec +{ + int channels; + int sample_rate; + mpeg3_demuxer_t *demuxer; + mpeg3audio_t *audio; + long current_position; + long total_samples; +}; + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c b/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c new file mode 100644 index 0000000..20f7660 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c @@ -0,0 +1,225 @@ +/* Concatenate elementary streams */ + +#include "libmpeg3.h" + +#include +#include +#include + +#define MPEG3_SEQUENCE_START_CODE 0x000001b3 +#define BUFFER_SIZE 1000000 + +int main(int argc, char *argv[]) +{ + char inpath[1024]; + mpeg3_t *in; + int current_file, current_output_file = 0, i; + unsigned int bits; + unsigned char *buffer; + long output_size; + int result = 0; + long total_frames = 0; + int do_audio = 0, do_video = 0; + int stream = 0; + + if(argc < 2) + { + fprintf(stderr, "Concatenate elementary streams or demultiplex a program stream.\n" + "Usage: mpeg3cat -[av0123456789] [infile...] > \n\n" + "Example: Concatenate 2 video files: mpeg3cat xena1.m2v xena2.m2v > xena.m2v\n" + " Extract audio stream 0: mpeg3cat -a0 xena.vob > war_cry.ac3\n"); + exit(1); + } + + for(i = 1; i < argc; i++) + { + if(argv[i][0] == '-') + { + if(argv[i][1] != 'a' && argv[i][1] != 'v') + { + fprintf(stderr, "invalid option %s\n", argv[i]); + } + else + { + if(argv[i][1] == 'a') do_audio = 1; + else + if(argv[i][1] == 'v') do_video = 1; + + if(argv[i][2] != 0) + { + stream = argv[i][2] - 48; + } + } + } + } + + buffer = (unsigned char*)malloc(BUFFER_SIZE); + + for(current_file = 1; current_file < argc; current_file++) + { + if(argv[current_file][0] == '-') continue; + + strcpy(inpath, argv[current_file]); + if(!(in = mpeg3_open(inpath))) + { + fprintf(stderr, "Skipping %s\n", inpath); + continue; + } + + if((mpeg3_has_audio(in) && in->is_audio_stream) || + (do_audio && !in->is_audio_stream && !in->is_video_stream)) + { + do_audio = 1; +/* Add audio stream to end */ + while(!mpeg3_read_audio_chunk(in, buffer, + &output_size, + BUFFER_SIZE, + stream)) + { + result = !fwrite(buffer, output_size, 1, stdout); + if(result) + { + perror("fwrite audio chunk"); + break; + } + } + } + else + if((mpeg3_has_video(in) && in->is_video_stream) || + (do_video && !in->is_video_stream && !in->is_audio_stream)) + { +/* Add video stream to end */ + int hour, minute, second, frame; + long gop_frame; + unsigned long code; + float carry; + int i, offset; + + do_video = 1; + while(!mpeg3_read_video_chunk(in, + buffer, + &output_size, + BUFFER_SIZE, + stream) && + output_size >= 4) + { + code = (unsigned long)buffer[output_size - 4] << 24; + code |= (unsigned long)buffer[output_size - 3] << 16; + code |= (unsigned long)buffer[output_size - 2] << 8; + code |= (unsigned long)buffer[output_size - 1]; + +/* Got a frame at the end of this buffer. */ + if(code == MPEG3_PICTURE_START_CODE) + { + total_frames++; + } + else + if(code == MPEG3_SEQUENCE_END_CODE) + { +/* Got a sequence end code at the end of this buffer. */ + output_size -= 4; + } + + code = (unsigned long)buffer[0] << 24; + code |= (unsigned long)buffer[1] << 16; + code |= (unsigned long)buffer[2] << 8; + code |= buffer[3]; + + i = 0; + offset = 0; + if(code == MPEG3_SEQUENCE_START_CODE && current_output_file > 0) + { +/* Skip the sequence start code */ + i += 4; + while(i < output_size && + code != MPEG3_GOP_START_CODE) + { + code <<= 8; + code |= buffer[i++]; + } + i -= 4; + offset = i; + } + +/* Search for GOP header to fix */ + code = (unsigned long)buffer[i++] << 24; + code |= (unsigned long)buffer[i++] << 16; + code |= (unsigned long)buffer[i++] << 8; + code |= buffer[i++]; + while(i < output_size && + code != MPEG3_GOP_START_CODE) + { + code <<= 8; + code |= buffer[i++]; + } + + if(code == MPEG3_GOP_START_CODE) + { +/* Get the time code */ + code = (unsigned long)buffer[i] << 24; + code |= (unsigned long)buffer[i + 1] << 16; + code |= (unsigned long)buffer[i + 2] << 8; + code |= (unsigned long)buffer[i + 3]; + + hour = code >> 26 & 0x1f; + minute = code >> 20 & 0x3f; + second = code >> 13 & 0x3f; + frame = code >> 7 & 0x3f; + + gop_frame = (long)(hour * 3600 * mpeg3_frame_rate(in, stream) + + minute * 60 * mpeg3_frame_rate(in, stream) + + second * mpeg3_frame_rate(in, stream) + + frame); +/* fprintf(stderr, "old: %02d:%02d:%02d:%02d ", hour, minute, second, frame); */ +/* Write a new time code */ + hour = (long)((float)(total_frames - 1) / mpeg3_frame_rate(in, stream) / 3600); + carry = hour * 3600 * mpeg3_frame_rate(in, stream); + minute = (long)((float)(total_frames - 1 - carry) / mpeg3_frame_rate(in, stream) / 60); + carry += minute * 60 * mpeg3_frame_rate(in, stream); + second = (long)((float)(total_frames - 1 - carry) / mpeg3_frame_rate(in, stream)); + carry += second * mpeg3_frame_rate(in, stream); + frame = (int)(total_frames - 1 - carry); + + buffer[i] = ((code >> 24) & 0x80) | (hour << 2) | (minute >> 4); + buffer[i + 1] = ((code >> 16) & 0x08) | ((minute & 0xf) << 4) | (second >> 3); + buffer[i + 2] = ((second & 0x7) << 5) | (frame >> 1); + buffer[i + 3] = (code & 0x7f) | ((frame & 0x1) << 7); +/* fprintf(stderr, "new: %02d:%02d:%02d:%02d\n", hour, minute, second, frame); */ + } + +/* Write the frame */ + result = !fwrite(buffer + offset, output_size - offset, 1, stdout); + if(result) + { + perror("fwrite video chunk"); + break; + } + } + } + else + { + fprintf(stderr, "Unsupported stream type.\n"); + mpeg3_close(in); + in = 0; + continue; + } + + mpeg3_close(in); + in = 0; + current_output_file++; + } + +/* Terminate output */ + if(current_output_file > 0 && do_video) + { +/*fprintf(stderr, "\n"); */ +/* Write new end of sequence */ + buffer[0] = MPEG3_SEQUENCE_END_CODE >> 24; + buffer[1] = (MPEG3_SEQUENCE_END_CODE >> 16) & 0xff; + buffer[2] = (MPEG3_SEQUENCE_END_CODE >> 8) & 0xff; + buffer[3] = MPEG3_SEQUENCE_END_CODE & 0xff; + result = !fwrite(buffer, 4, 1, stdout); + } + + exit(0); +} diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3css.c b/core/multimedia/opieplayer/libmpeg3/mpeg3css.c new file mode 100644 index 0000000..7f9ad8c --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3css.c @@ -0,0 +1,32 @@ +#include "mpeg3css.h" +#include "mpeg3private.h" + +extern "C" { + +int mpeg3_init_css(mpeg3_t *file, mpeg3_css_t *css) +{ + return 0; +} + +int mpeg3_get_keys(mpeg3_css_t *css, char *path) +{ + return 1; +} + +int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector) +{ + return 1; +} + +mpeg3_css_t* mpeg3_new_css() +{ + return 0; +} + +int mpeg3_delete_css(mpeg3_css_t *css) +{ + return 0; +} + +}; + diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3css.h b/core/multimedia/opieplayer/libmpeg3/mpeg3css.h new file mode 100644 index 0000000..1272574 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3css.h @@ -0,0 +1,29 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3CSS_H +#define MPEG3CSS_H + +/* Stubs for deCSS which can't be distributed legally */ + +typedef struct +{ +} mpeg3_css_t; + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.c b/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.c new file mode 100644 index 0000000..0901195 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.c @@ -0,0 +1,19 @@ +/* Stubs for deCSS which can't be distributed in source form */ + +#include "mpeg3css.h" +#include "mpeg3private.h" + +int mpeg3_init_css(mpeg3_t *file, mpeg3_css_t *css) +{ + return 0; +} + +int mpeg3_get_keys(mpeg3_css_t *css, char *path) +{ + return 1; +} + +int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector) +{ + return 1; +} diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.h b/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.h new file mode 100644 index 0000000..1272574 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.h @@ -0,0 +1,29 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3CSS_H +#define MPEG3CSS_H + +/* Stubs for deCSS which can't be distributed legally */ + +typedef struct +{ +} mpeg3_css_t; + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3demux.c b/core/multimedia/opieplayer/libmpeg3/mpeg3demux.c new file mode 100644 index 0000000..cccc820 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3demux.c @@ -0,0 +1,1849 @@ +#include "libmpeg3.h" +#include "mpeg3io.h" +#include "mpeg3protos.h" + +#include +#include +#include + +#define ABS(x) ((x) >= 0 ? (x) : -(x)) + +/* Don't advance pointer */ +static inline unsigned char mpeg3packet_next_char(mpeg3_demuxer_t *demuxer) +{ + return demuxer->raw_data[demuxer->raw_offset]; +} + +unsigned char mpeg3packet_read_char(mpeg3_demuxer_t *demuxer) +{ + unsigned char result = demuxer->raw_data[demuxer->raw_offset++]; + return result; +} + +static inline unsigned int mpeg3packet_read_int16(mpeg3_demuxer_t *demuxer) +{ + unsigned int a, b, result; + a = demuxer->raw_data[demuxer->raw_offset++]; + b = demuxer->raw_data[demuxer->raw_offset++]; + result = (a << 8) | b; + + return result; +} + +static inline unsigned int mpeg3packet_next_int24(mpeg3_demuxer_t *demuxer) +{ + unsigned int a, b, c, result; + a = demuxer->raw_data[demuxer->raw_offset]; + b = demuxer->raw_data[demuxer->raw_offset + 1]; + c = demuxer->raw_data[demuxer->raw_offset + 2]; + result = (a << 16) | (b << 8) | c; + + return result; +} + +static inline unsigned int mpeg3packet_read_int24(mpeg3_demuxer_t *demuxer) +{ + unsigned int a, b, c, result; + a = demuxer->raw_data[demuxer->raw_offset++]; + b = demuxer->raw_data[demuxer->raw_offset++]; + c = demuxer->raw_data[demuxer->raw_offset++]; + result = (a << 16) | (b << 8) | c; + + return result; +} + +static inline unsigned int mpeg3packet_read_int32(mpeg3_demuxer_t *demuxer) +{ + unsigned int a, b, c, d, result; + a = demuxer->raw_data[demuxer->raw_offset++]; + b = demuxer->raw_data[demuxer->raw_offset++]; + c = demuxer->raw_data[demuxer->raw_offset++]; + d = demuxer->raw_data[demuxer->raw_offset++]; + result = (a << 24) | (b << 16) | (c << 8) | d; + + return result; +} + +static inline unsigned int mpeg3packet_skip(mpeg3_demuxer_t *demuxer, long length) +{ + demuxer->raw_offset += length; + return 0; +} + +int mpeg3_get_adaptation_field(mpeg3_demuxer_t *demuxer) +{ + long length; + int pcr_flag; + + demuxer->adaptation_fields++; +/* get adaptation field length */ + length = mpeg3packet_read_char(demuxer); +/* get first byte */ + pcr_flag = (mpeg3packet_read_char(demuxer) >> 4) & 1; + + if(pcr_flag) + { + unsigned long clk_ref_base = mpeg3packet_read_int32(demuxer); + unsigned int clk_ref_ext = mpeg3packet_read_int16(demuxer); + + if (clk_ref_base > 0x7fffffff) + { /* correct for invalid numbers */ + clk_ref_base = 0; /* ie. longer than 32 bits when multiplied by 2 */ + clk_ref_ext = 0; /* multiplied by 2 corresponds to shift left 1 (<<=1) */ + } + else + { + clk_ref_base <<= 1; /* Create space for bit */ + clk_ref_base |= (clk_ref_ext >> 15); /* Take bit */ + clk_ref_ext &= 0x01ff; /* Only lower 9 bits */ + } + demuxer->time = clk_ref_base + clk_ref_ext / 300; + if(length) mpeg3packet_skip(demuxer, length - 7); + } + else + mpeg3packet_skip(demuxer, length - 1); + + return 0; +} + +int mpeg3_get_program_association_table(mpeg3_demuxer_t *demuxer) +{ + demuxer->program_association_tables++; + demuxer->table_id = mpeg3packet_read_char(demuxer); + demuxer->section_length = mpeg3packet_read_int16(demuxer) & 0xfff; + demuxer->transport_stream_id = mpeg3packet_read_int16(demuxer); + mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset); + return 0; +} + +int mpeg3packet_get_data_buffer(mpeg3_demuxer_t *demuxer) +{ + while(demuxer->raw_offset < demuxer->raw_size && demuxer->data_size < demuxer->data_allocated) + { + demuxer->data_buffer[demuxer->data_size++] = demuxer->raw_data[demuxer->raw_offset++]; + } + return 0; +} + +int mpeg3_get_pes_packet_header(mpeg3_demuxer_t *demuxer, unsigned long *pts, unsigned long *dts) +{ + unsigned int pes_header_bytes = 0; + unsigned int pts_dts_flags; + int pes_header_data_length; + +/* drop first 8 bits */ + mpeg3packet_read_char(demuxer); + pts_dts_flags = (mpeg3packet_read_char(demuxer) >> 6) & 0x3; + pes_header_data_length = mpeg3packet_read_char(demuxer); + +/* Get Presentation Time stamps and Decoding Time Stamps */ + if(pts_dts_flags == 2) + { + *pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */ + *pts <<= 15; + *pts |= (mpeg3packet_read_int16(demuxer) >> 1); + *pts <<= 15; + *pts |= (mpeg3packet_read_int16(demuxer) >> 1); + pes_header_bytes += 5; + } + else if(pts_dts_flags == 3) + { + *pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */ + *pts <<= 15; + *pts |= (mpeg3packet_read_int16(demuxer) >> 1); + *pts <<= 15; + *pts |= (mpeg3packet_read_int16(demuxer) >> 1); + *dts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */ + *dts <<= 15; + *dts |= (mpeg3packet_read_int16(demuxer) >> 1); + *dts <<= 15; + *dts |= (mpeg3packet_read_int16(demuxer) >> 1); + pes_header_bytes += 10; + } +/* extract other stuff here! */ + + mpeg3packet_skip(demuxer, pes_header_data_length - pes_header_bytes); + return 0; +} + +int get_unknown_data(mpeg3_demuxer_t *demuxer) +{ + mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset); + return 0; +} + +int mpeg3_get_pes_packet_data(mpeg3_demuxer_t *demuxer, unsigned int stream_id) +{ + unsigned long pts = 0, dts = 0; + + if((stream_id >> 4) == 12 || (stream_id >> 4) == 13) + { +/* Just pick the first available stream if no ID is set */ + if(demuxer->astream == -1) + demuxer->astream = (stream_id & 0x0f); + + if((stream_id & 0x0f) == demuxer->astream && demuxer->do_audio) + { + mpeg3_get_pes_packet_header(demuxer, &pts, &dts); + demuxer->pes_audio_time = pts; + demuxer->audio_pid = demuxer->pid; + return mpeg3packet_get_data_buffer(demuxer); + } + } + else + if((stream_id >> 4)==14) + { +/* Just pick the first available stream if no ID is set */ + if(demuxer->vstream == -1) + demuxer->vstream = (stream_id & 0x0f); + + if((stream_id & 0x0f) == demuxer->vstream && demuxer->do_video) + { + mpeg3_get_pes_packet_header(demuxer, &pts, &dts); + demuxer->pes_video_time = pts; + demuxer->video_pid = demuxer->pid; + return mpeg3packet_get_data_buffer(demuxer); + } + } + else + { + return get_unknown_data(demuxer); + } + + mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset); + + return 0; +} + +int mpeg3_get_pes_packet(mpeg3_demuxer_t *demuxer) +{ + unsigned int stream_id; + + demuxer->pes_packets++; + stream_id = mpeg3packet_read_char(demuxer); +/* Skip startcode */ + mpeg3packet_read_int24(demuxer); +/* Skip pes packet length */ + mpeg3packet_read_int16(demuxer); + + if(stream_id != MPEG3_PRIVATE_STREAM_2 && stream_id != MPEG3_PADDING_STREAM) + { + return mpeg3_get_pes_packet_data(demuxer, stream_id); + } + else + if(stream_id == MPEG3_PRIVATE_STREAM_2) + { +/* Dump private data! */ + fprintf(stderr, "stream_id == MPEG3_PRIVATE_STREAM_2\n"); + mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset); + return 0; + } + else + if(stream_id == MPEG3_PADDING_STREAM) + { + mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset); + return 0; + } + else + { + fprintf(stderr, "unknown stream_id in pes packet"); + return 1; + } + return 0; +} + +int mpeg3_get_payload(mpeg3_demuxer_t *demuxer) +{ + if(demuxer->payload_unit_start_indicator) + { + if(demuxer->pid==0) mpeg3_get_program_association_table(demuxer); + else + if(mpeg3packet_next_int24(demuxer) == MPEG3_PACKET_START_CODE_PREFIX) mpeg3_get_pes_packet(demuxer); + else + mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset); + } + else + { + if(demuxer->pid == demuxer->audio_pid && demuxer->do_audio) + { + mpeg3packet_get_data_buffer(demuxer); + } + else + if(demuxer->pid == demuxer->video_pid && demuxer->do_video) + { + mpeg3packet_get_data_buffer(demuxer); + } + else + mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset); + } + return 0; +} + +/* Read a transport packet */ +int mpeg3_read_transport(mpeg3_demuxer_t *demuxer) +{ + mpeg3_title_t *title = demuxer->titles[demuxer->current_title]; + int result = mpeg3io_read_data(demuxer->raw_data, demuxer->packet_size, title->fs); + unsigned int bits; + int table_entry; + + demuxer->raw_size = demuxer->packet_size; + demuxer->raw_offset = 0; + if(result) + { + perror("mpeg3_read_transport"); + return 1; + } + +/* Sync byte */ + if(mpeg3packet_read_char(demuxer) != MPEG3_SYNC_BYTE) + { + fprintf(stderr, "mpeg3packet_read_char(demuxer) != MPEG3_SYNC_BYTE\n"); + return 1; + } + +/* bits = mpeg3packet_read_int24(demuxer) & 0x0000ffff; */ +/* demuxer->transport_error_indicator = bits >> 15; */ +/* demuxer->payload_unit_start_indicator = (bits >> 14) & 1; */ +/* demuxer->pid = bits & 0x00001fff; */ +/* demuxer->transport_scrambling_control = (mpeg3packet_next_char(demuxer) >> 6) & 0x3; */ +/* demuxer->adaptation_field_control = (mpeg3packet_next_char(demuxer) >> 4) & 0x3; */ +/* demuxer->continuity_counter = (mpeg3packet_read_char(demuxer) & 0xf); */ + + bits = mpeg3packet_read_int24(demuxer) & 0x00ffffff; + demuxer->transport_error_indicator = (bits >> 23) & 0x1; + demuxer->payload_unit_start_indicator = (bits >> 22) & 0x1; + demuxer->pid = (bits >> 8) & 0x00001fff; + demuxer->transport_scrambling_control = (bits >> 6) & 0x3; + demuxer->adaptation_field_control = (bits >> 4) & 0x3; + demuxer->continuity_counter = bits & 0xf; + + if(demuxer->transport_error_indicator) + { + fprintf(stderr, "demuxer->transport_error_indicator\n"); + return 1; + } + + if (demuxer->pid == 0x1fff) + { + demuxer->is_padding = 1; /* padding; just go to next */ + return 0; + } + else + { + demuxer->is_padding = 0; + } + +/* Get pid */ + for(table_entry = 0, result = 0; table_entry < demuxer->total_pids; table_entry++) + { + if(demuxer->pid == demuxer->pid_table[table_entry]) + { + result = 1; + break; + } + } + +/* Not in pid table */ + if(!result) + { + demuxer->pid_table[table_entry] = demuxer->pid; + demuxer->continuity_counters[table_entry] = demuxer->continuity_counter; /* init */ + demuxer->total_pids++; + } + result = 0; + +/* Check counters */ + if(demuxer->pid != MPEG3_PROGRAM_ASSOCIATION_TABLE && + demuxer->pid != MPEG3_CONDITIONAL_ACCESS_TABLE && + (demuxer->adaptation_field_control == 1 || demuxer->adaptation_field_control == 3)) + { + if(demuxer->continuity_counters[table_entry] != demuxer->continuity_counter) + { + fprintf(stderr, "demuxer->continuity_counters[table_entry] != demuxer->continuity_counter\n"); +/* Reset it */ + demuxer->continuity_counters[table_entry] = demuxer->continuity_counter; + } + if(++(demuxer->continuity_counters[table_entry]) > 15) demuxer->continuity_counters[table_entry] = 0; + } + + if(demuxer->adaptation_field_control == 2 || demuxer->adaptation_field_control == 3) + result = mpeg3_get_adaptation_field(demuxer); + + if(demuxer->adaptation_field_control == 1 || demuxer->adaptation_field_control == 3) + result = mpeg3_get_payload(demuxer); + + return result; +} + +int mpeg3_get_system_header(mpeg3_demuxer_t *demuxer) +{ + int length = mpeg3packet_read_int16(demuxer); + mpeg3packet_skip(demuxer, length); + return 0; +} + +unsigned long mpeg3_get_timestamp(mpeg3_demuxer_t *demuxer) +{ + unsigned long timestamp; +/* Only low 4 bits (7==1111) */ + timestamp = (mpeg3packet_read_char(demuxer) >> 1) & 7; + timestamp <<= 15; + timestamp |= (mpeg3packet_read_int16(demuxer) >> 1); + timestamp <<= 15; + timestamp |= (mpeg3packet_read_int16(demuxer) >> 1); + return timestamp; +} + +int mpeg3_get_pack_header(mpeg3_demuxer_t *demuxer, unsigned int *header) +{ + unsigned long i, j; + unsigned long clock_ref, clock_ref_ext; + +/* Get the time code */ + if((mpeg3packet_next_char(demuxer) >> 4) == 2) + { +/* MPEG-1 */ + demuxer->time = (double)mpeg3_get_timestamp(demuxer) / 90000; +/* Skip 3 bytes */ + mpeg3packet_read_int24(demuxer); + } + else + if(mpeg3packet_next_char(demuxer) & 0x40) + { + i = mpeg3packet_read_int32(demuxer); + j = mpeg3packet_read_int16(demuxer); + if(i & 0x40000000 || (i >> 28) == 2) + { + clock_ref = ((i & 0x31000000) << 3); + clock_ref |= ((i & 0x03fff800) << 4); + clock_ref |= ((i & 0x000003ff) << 5); + clock_ref |= ((j & 0xf800) >> 11); + clock_ref_ext = (j >> 1) & 0x1ff; + + demuxer->time = (double)(clock_ref + clock_ref_ext / 300) / 90000; +/* Skip 3 bytes */ + mpeg3packet_read_int24(demuxer); + i = mpeg3packet_read_char(demuxer) & 0x7; + +/* stuffing */ + mpeg3packet_skip(demuxer, i); + } + } + else + { + mpeg3packet_skip(demuxer, 2); + } + + *header = mpeg3packet_read_int32(demuxer); + if(*header == MPEG3_SYSTEM_START_CODE) + { + mpeg3_get_system_header(demuxer); + *header = mpeg3packet_read_int32(demuxer); + } + return 0; +} + +/* Program packet reading core */ +int mpeg3_get_ps_pes_packet(mpeg3_demuxer_t *demuxer, unsigned int *header) +{ + unsigned long pts = 0, dts = 0; + int stream_id; + int pes_packet_length; + int pes_packet_start; + int i; + mpeg3_t *file = demuxer->file; + + stream_id = *header & 0xff; + pes_packet_length = mpeg3packet_read_int16(demuxer); + pes_packet_start = demuxer->raw_offset; + + if(stream_id != MPEG3_PRIVATE_STREAM_2 && + stream_id != MPEG3_PADDING_STREAM) + { + if((mpeg3packet_next_char(demuxer) >> 6) == 0x02) + { +/* Get MPEG-2 packet */ + int pes_header_bytes = 0; + int scrambling = (mpeg3packet_read_char(demuxer) >> 4) & 0x3; + int pts_dts_flags = (mpeg3packet_read_char(demuxer) >> 6) & 0x3; + int pes_header_data_length = mpeg3packet_read_char(demuxer); + + if(scrambling && (demuxer->do_audio || demuxer->do_video)) + { +/* Decrypt it */ + if(mpeg3_decrypt_packet(demuxer->titles[demuxer->current_title]->fs->css, + demuxer->raw_data)) + { + fprintf(stderr, "mpeg3_get_ps_pes_packet: Decryption not available\n"); + return 1; + } + } + +/* Get Presentation and Decoding Time Stamps */ + if(pts_dts_flags == 2) + { + pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */ + pts <<= 15; + pts |= (mpeg3packet_read_int16(demuxer) >> 1); + pts <<= 15; + pts |= (mpeg3packet_read_int16(demuxer) >> 1); + pes_header_bytes += 5; + } + else + if(pts_dts_flags == 3) + { + pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */ + pts <<= 15; + pts |= (mpeg3packet_read_int16(demuxer) >> 1); + pts <<= 15; + pts |= (mpeg3packet_read_int16(demuxer) >> 1); + dts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */ + dts <<= 15; + dts |= (mpeg3packet_read_int16(demuxer) >> 1); + dts <<= 15; + dts |= (mpeg3packet_read_int16(demuxer) >> 1); + pes_header_bytes += 10; + } + +/* Skip unknown */ + mpeg3packet_skip(demuxer, pes_header_data_length - pes_header_bytes); + } + else + { + int pts_dts_flags; +/* Get MPEG-1 packet */ + while(mpeg3packet_next_char(demuxer) == 0xff) + { + mpeg3packet_read_char(demuxer); + } + +/* Skip STD buffer scale */ + if((mpeg3packet_next_char(demuxer) & 0x40) == 0x40) + { + mpeg3packet_skip(demuxer, 2); + } + +/* Decide which timestamps are available */ + pts_dts_flags = mpeg3packet_next_char(demuxer); + + if(pts_dts_flags >= 0x30) + { +/* Get the presentation and decoding time stamp */ + pts = mpeg3_get_timestamp(demuxer); + dts = mpeg3_get_timestamp(demuxer); + } + else + if(pts_dts_flags >= 0x20) + { +/* Get just the presentation time stamp */ + pts = mpeg3_get_timestamp(demuxer); + } + else + if(pts_dts_flags == 0x0f) + { +/* End of timestamps */ + mpeg3packet_read_char(demuxer); + } + else + { + return 1; /* Error */ + } + } + +/* Now extract the payload. */ + if((stream_id >> 4) == 0xc || (stream_id >> 4) == 0xd) + { +/* Audio data */ +/* Take first stream ID if -1 */ + pes_packet_length -= demuxer->raw_offset - pes_packet_start; + if(!demuxer->do_audio && !demuxer->do_video) + demuxer->astream_table[stream_id & 0x0f] = AUDIO_MPEG; + else + if(demuxer->astream == -1) + demuxer->astream = stream_id & 0x0f; + + if((stream_id & 0x0f) == demuxer->astream && demuxer->do_audio) + { + if(pts) demuxer->pes_audio_time = pts; + + memcpy(&demuxer->data_buffer[demuxer->data_size], + &demuxer->raw_data[demuxer->raw_offset], + pes_packet_length); + demuxer->data_size += pes_packet_length; + demuxer->raw_offset += pes_packet_length; + } + else + { + mpeg3packet_skip(demuxer, pes_packet_length); + } + } + else + if((stream_id >> 4) == 0xe) + { +/* Video data */ +/* Take first stream ID if -1 */ + if(!demuxer->do_audio && !demuxer->do_video) + demuxer->vstream_table[stream_id & 0x0f] = 1; + else + if(demuxer->vstream == -1) + demuxer->vstream = stream_id & 0x0f; + + pes_packet_length -= demuxer->raw_offset - pes_packet_start; + if((stream_id & 0x0f) == demuxer->vstream && demuxer->do_video) + { + if(pts) demuxer->pes_video_time = pts; + + memcpy(&demuxer->data_buffer[demuxer->data_size], + &demuxer->raw_data[demuxer->raw_offset], + pes_packet_length); + demuxer->data_size += pes_packet_length; + demuxer->raw_offset += pes_packet_length; + } + else + { + mpeg3packet_skip(demuxer, pes_packet_length); + } + } + else + if(stream_id == 0xbd && demuxer->raw_data[demuxer->raw_offset] != 0xff) + { +/* DVD audio data */ +/* Get the audio format */ + int format; + if((demuxer->raw_data[demuxer->raw_offset] & 0xf0) == 0xa0) + format = AUDIO_PCM; + else + format = AUDIO_AC3; + + stream_id = demuxer->raw_data[demuxer->raw_offset] - 0x80; + +/* Take first stream ID if not building TOC. */ + if(!demuxer->do_audio && !demuxer->do_video) + demuxer->astream_table[stream_id] = format; + else + if(demuxer->astream == -1) + demuxer->astream = stream_id; + + if(stream_id == demuxer->astream && demuxer->do_audio) + { + demuxer->aformat = format; + if(pts) demuxer->pes_audio_time = pts; + mpeg3packet_read_int32(demuxer); + pes_packet_length -= demuxer->raw_offset - pes_packet_start; + + memcpy(&demuxer->data_buffer[demuxer->data_size], + &demuxer->raw_data[demuxer->raw_offset], + pes_packet_length); + demuxer->data_size += pes_packet_length; + demuxer->raw_offset += pes_packet_length; + } + else + { + pes_packet_length -= demuxer->raw_offset - pes_packet_start; + mpeg3packet_skip(demuxer, pes_packet_length); + } + } + else + if(stream_id == 0xbc || 1) + { + pes_packet_length -= demuxer->raw_offset - pes_packet_start; + mpeg3packet_skip(demuxer, pes_packet_length); + } + } + else + if(stream_id == MPEG3_PRIVATE_STREAM_2 || stream_id == MPEG3_PADDING_STREAM) + { + pes_packet_length -= demuxer->raw_offset - pes_packet_start; + mpeg3packet_skip(demuxer, pes_packet_length); + } + + while(demuxer->raw_offset + 4 < demuxer->raw_size) + { + *header = mpeg3packet_read_int32(demuxer); + if((*header >> 8) != MPEG3_PACKET_START_CODE_PREFIX) + demuxer->raw_offset -= 3; + else + break; + } + + return 0; +} + +int mpeg3_read_program(mpeg3_demuxer_t *demuxer) +{ + int result = 0, count = 0; + mpeg3_t *file = demuxer->file; + mpeg3_title_t *title = demuxer->titles[demuxer->current_title]; + unsigned int header; + demuxer->raw_size = demuxer->packet_size; + demuxer->raw_offset = 0; + demuxer->data_size = 0; + +/* Search backward for it. */ + header = mpeg3io_read_int32(title->fs); + result = mpeg3io_eof(title->fs); + + if(!result) result = mpeg3io_seek_relative(title->fs, -4); + +// Search backwards for header + while(header != MPEG3_PACK_START_CODE && !result && count < demuxer->packet_size) + { + result = mpeg3io_seek_relative(title->fs, -1); + if(!result) + { + header >>= 8; + header |= mpeg3io_read_char(title->fs) << 24; + result = mpeg3io_seek_relative(title->fs, -1); + } + count++; + } + + if(result) + { +// couldn't find MPEG3_PACK_START_CODE + return 1; + } + + result = mpeg3io_read_data(demuxer->raw_data, demuxer->packet_size, title->fs); + + if(result) + { + perror("mpeg3_read_program"); + return 1; + } + + header = mpeg3packet_read_int32(demuxer); + while(demuxer->raw_offset + 4 < demuxer->raw_size && !result) + { + if(header == MPEG3_PACK_START_CODE) + { + result = mpeg3_get_pack_header(demuxer, &header); + } + else + if((header >> 8) == MPEG3_PACKET_START_CODE_PREFIX) + { + result = mpeg3_get_ps_pes_packet(demuxer, &header); + } + } + return result; +} + +double mpeg3_lookup_time_offset(mpeg3_demuxer_t *demuxer, long byte) +{ + int i; + mpeg3_title_t *title = demuxer->titles[demuxer->current_title]; + + if(!title->timecode_table_size) return 0; + + for(i = title->timecode_table_size - 1; + i >= 0 && title->timecode_table[i].start_byte > byte; + i--) + ; + if(i < 0) i = 0; + return title->timecode_table[i].absolute_start_time - title->timecode_table[i].start_time; +} + +int mpeg3_advance_timecode(mpeg3_demuxer_t *demuxer, int reverse) +{ + mpeg3_title_t *title = demuxer->titles[demuxer->current_title]; + int result = 0; + int do_seek = 0; + +/* Skip timecode advancing when constructing timecode table */ + if(!title->timecode_table || + !title->timecode_table_size || + demuxer->generating_timecode) return 0; + + if(!reverse) + { +/* Get inside the current timecode */ + if(mpeg3io_tell(title->fs) < title->timecode_table[demuxer->current_timecode].start_byte) + { + mpeg3io_seek(title->fs, title->timecode_table[demuxer->current_timecode].start_byte); + } + +/* Get the next timecode */ + while(!result && + (mpeg3io_tell(title->fs) >= title->timecode_table[demuxer->current_timecode].end_byte || + demuxer->current_program != title->timecode_table[demuxer->current_timecode].program)) + { + +/* + * printf("mpeg3_advance_timecode %d %d %d %d\n", mpeg3io_tell(title->fs), title->timecode_table[demuxer->current_timecode].end_byte, + * demuxer->current_program, title->timecode_table[demuxer->current_timecode].program); + */ + + demuxer->current_timecode++; + if(demuxer->current_timecode >= title->timecode_table_size) + { + demuxer->current_timecode = 0; + if(demuxer->current_title + 1 < demuxer->total_titles) + { + mpeg3demux_open_title(demuxer, demuxer->current_title + 1); + do_seek = 1; + } + else + { + mpeg3io_seek(title->fs, mpeg3io_total_bytes(title->fs)); + result = 1; + } + } + title = demuxer->titles[demuxer->current_title]; + } + + if(!result && do_seek) + { + mpeg3io_seek(title->fs, title->timecode_table[demuxer->current_timecode].start_byte); + } + } + else + { +/* Get the previous timecode */ + while(!result && + (mpeg3io_tell(title->fs) < title->timecode_table[demuxer->current_timecode].start_byte || + demuxer->current_program != title->timecode_table[demuxer->current_timecode].program)) + { +/* + * if(demuxer->do_audio) printf("mpeg3_reverse_timecode %d %d %d %d\n", mpeg3io_tell(title->fs), title->timecode_table[demuxer->current_timecode].end_byte, + * demuxer->current_program, title->timecode_table[demuxer->current_timecode].program); + */ + demuxer->current_timecode--; + if(demuxer->current_timecode < 0) + { + if(demuxer->current_title > 0) + { + mpeg3demux_open_title(demuxer, demuxer->current_title - 1); + title = demuxer->titles[demuxer->current_title]; + demuxer->current_timecode = title->timecode_table_size - 1; + do_seek = 1; + } + else + { + mpeg3io_seek(title->fs, 0); + demuxer->current_timecode = 0; + result = 1; + } + } + } + + if(!result && do_seek) + mpeg3io_seek(title->fs, title->timecode_table[demuxer->current_timecode].start_byte); + } + + return result; +} + +/* Read packet in the forward direction */ +int mpeg3_read_next_packet(mpeg3_demuxer_t *demuxer) +{ + int result = 0; + long current_position; + mpeg3_t *file = demuxer->file; + mpeg3_title_t *title = demuxer->titles[demuxer->current_title]; + demuxer->data_size = 0; + demuxer->data_position = 0; + +/* Flip the file descriptor back to the end of the packet for forward */ +/* reading. */ + if(demuxer->reverse) + { + result = mpeg3io_seek_relative(title->fs, demuxer->packet_size); + demuxer->reverse = 0; + } + +/* Read packets until the output buffer is full */ + if(!result) + { + do + { + result = mpeg3_advance_timecode(demuxer, 0); + + if(!result) + { + demuxer->time_offset = mpeg3_lookup_time_offset(demuxer, mpeg3io_tell(title->fs)); + + if(file->is_transport_stream) + { + result = mpeg3_read_transport(demuxer); + } + else + if(file->is_program_stream) + { + result = mpeg3_read_program(demuxer); + } + else + { +/* Read elementary stream. */ + result = mpeg3io_read_data(demuxer->data_buffer, demuxer->packet_size, title->fs); + if(!result) demuxer->data_size = demuxer->packet_size; + } + } + }while(!result && demuxer->data_size == 0 && (demuxer->do_audio || demuxer->do_video)); + } + + return result; +} + +/* Read the packet right before the packet we're currently on. */ +int mpeg3_read_prev_packet(mpeg3_demuxer_t *demuxer) +{ + int result = 0; + mpeg3_t *file = demuxer->file; + long current_position; + mpeg3_title_t *title = demuxer->titles[demuxer->current_title]; + + demuxer->data_size = 0; + demuxer->data_position = 0; + + do + { +/* Rewind to the start of the packet to be read. */ + result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size); + + if(!result) result = mpeg3_advance_timecode(demuxer, 1); + if(!result) demuxer->time_offset = mpeg3_lookup_time_offset(demuxer, mpeg3io_tell(title->fs)); + + if(file->is_transport_stream && !result) + { + result = mpeg3_read_transport(demuxer); + if(!mpeg3io_bof(title->fs)) + /* if(!result) */result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size); + } + else + if(file->is_program_stream && !result) + { + + result = mpeg3_read_program(demuxer); + if(!mpeg3io_bof(title->fs)) + /* if(!result) */result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size); + } + else + if(!result) + { +/* Elementary stream */ +/* Read the packet forwards and seek back to the start */ + result = mpeg3io_read_data(demuxer->data_buffer, demuxer->packet_size, title->fs); + if(!result) + { + demuxer->data_size = demuxer->packet_size; + result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size); + } + } + }while(!result && demuxer->data_size == 0 && (demuxer->do_audio || demuxer->do_video)); + +/* Remember that the file descriptor is at the beginning of the packet just read. */ + demuxer->reverse = 1; + demuxer->error_flag = result; + return result; +} + + +/* Used for audio */ +int mpeg3demux_read_data(mpeg3_demuxer_t *demuxer, + unsigned char *output, + long size) +{ + long i; + int result = 0; + mpeg3_t *file = demuxer->file; + demuxer->error_flag = 0; + + if(demuxer->data_position >= 0) + { +/* Read forwards */ + for(i = 0; i < size && !result; ) + { + int fragment_size = size - i; + if(fragment_size > demuxer->data_size - demuxer->data_position) + fragment_size = demuxer->data_size - demuxer->data_position; + memcpy(output + i, demuxer->data_buffer + demuxer->data_position, fragment_size); + demuxer->data_position += fragment_size; + i += fragment_size; + + if(i < size) + { + result = mpeg3_read_next_packet(demuxer); + } + } + } + else + { +/* Read backwards a full packet. */ +/* Only good for reading less than the size of a full packet, but */ +/* this routine should only be used for searching for previous markers. */ + long current_position = demuxer->data_position; + result = mpeg3_read_prev_packet(demuxer); + if(!result) demuxer->data_position = demuxer->data_size + current_position; + memcpy(output, demuxer->data_buffer + demuxer->data_position, size); + demuxer->data_position += size; + } + + demuxer->error_flag = result; + return result; +} + +unsigned int mpeg3demux_read_char_packet(mpeg3_demuxer_t *demuxer) +{ + demuxer->error_flag = 0; + if(demuxer->data_position >= demuxer->data_size) + demuxer->error_flag = mpeg3_read_next_packet(demuxer); + demuxer->next_char = demuxer->data_buffer[demuxer->data_position++]; + return demuxer->next_char; +} + +unsigned int mpeg3demux_read_prev_char_packet(mpeg3_demuxer_t *demuxer) +{ + demuxer->error_flag = 0; + demuxer->data_position--; + if(demuxer->data_position < 0) + { + demuxer->error_flag = mpeg3_read_prev_packet(demuxer); + if(!demuxer->error_flag) demuxer->data_position = demuxer->data_size - 1; + } + demuxer->next_char = demuxer->data_buffer[demuxer->data_position]; + return demuxer->next_char; +} + +mpeg3demux_timecode_t* mpeg3_append_timecode(mpeg3_demuxer_t *demuxer, + mpeg3_title_t *title, + long prev_byte, + double prev_time, + long next_byte, + double next_time, + int dont_store) +{ + mpeg3demux_timecode_t *new_table; + mpeg3demux_timecode_t *new_timecode, *old_timecode; + long i; + + if(!title->timecode_table || + title->timecode_table_allocation <= title->timecode_table_size) + { + if(title->timecode_table_allocation == 0) + title->timecode_table_allocation = 1; + else + title->timecode_table_allocation *= 2; + + new_table = (mpeg3demux_timecode_t*)calloc(1, sizeof(mpeg3demux_timecode_t) * title->timecode_table_allocation); + if(title->timecode_table) + { + for(i = 0; i < title->timecode_table_size; i++) + { + new_table[i] = title->timecode_table[i]; + } + + free(title->timecode_table); + } + title->timecode_table = new_table; + } + + if(!dont_store) + { + new_timecode = &title->timecode_table[title->timecode_table_size]; + new_timecode->start_byte = next_byte; + new_timecode->start_time = next_time; + new_timecode->absolute_start_time = 0; + + if(title->timecode_table_size > 0) + { + old_timecode = &title->timecode_table[title->timecode_table_size - 1]; + old_timecode->end_byte = prev_byte; + old_timecode->end_time = prev_time; + new_timecode->absolute_start_time = + prev_time - + old_timecode->start_time + + old_timecode->absolute_start_time; + new_timecode->absolute_end_time = next_time; + } + } + + title->timecode_table_size++; + return new_timecode; +} + +mpeg3demux_timecode_t* mpeg3demux_next_timecode(mpeg3_demuxer_t *demuxer, + int *current_title, + int *current_timecode, + int current_program) +{ + int done = 0; + while(!done) + { +/* Increase timecode number */ + if(*current_timecode < demuxer->titles[*current_title]->timecode_table_size - 1) + { + (*current_timecode)++; + if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program) + return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]); + } + else +/* Increase title number */ + if(*current_title < demuxer->total_titles - 1) + { + (*current_title)++; + (*current_timecode) = 0; + if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program) + return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]); + } + else +/* End of disk */ + done = 1; + } + return 0; +} + +mpeg3demux_timecode_t* mpeg3demux_prev_timecode(mpeg3_demuxer_t *demuxer, + int *current_title, + int *current_timecode, + int current_program) +{ + int done = 0; + while(!done) + { +/* Increase timecode number */ + if(*current_timecode > 0) + { + (*current_timecode)--; + if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program) + return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]); + } + else +/* Increase title number */ + if(*current_title > 0) + { + (*current_title)--; + (*current_timecode) = demuxer->titles[*current_title]->timecode_table_size - 1; + if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program) + return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]); + } + else +/* End of disk */ + done = 1; + + } + return 0; +} + +int mpeg3demux_open_title(mpeg3_demuxer_t *demuxer, int title_number) +{ + mpeg3_title_t *title; + + if(title_number < demuxer->total_titles) + { + if(demuxer->current_title >= 0) + { + mpeg3io_close_file(demuxer->titles[demuxer->current_title]->fs); + demuxer->current_title = -1; + } + + title = demuxer->titles[title_number]; + if(mpeg3io_open_file(title->fs)) + { + demuxer->error_flag = 1; + perror("mpeg3demux_open_title"); + } + else + { + demuxer->current_title = title_number; + } + } + + demuxer->current_timecode = 0; + + return demuxer->error_flag; +} + +/* Assign program numbers to interleaved programs */ +int mpeg3demux_assign_programs(mpeg3_demuxer_t *demuxer) +{ + int current_program = 0; + int current_title = 0, previous_title; + int current_timecode = 0, previous_timecode; + double current_time, current_length; + int done = 0; + int interleaved = 0; + mpeg3demux_timecode_t *timecode1, *timecode2; + double program_times[MPEG3_MAX_STREAMS]; + int total_programs = 1; + int i, j; + int program_exists, last_program_assigned = 0; + int total_timecodes; + mpeg3_title_t **titles = demuxer->titles; + + for(i = 0, total_timecodes = 0; i < demuxer->total_titles; i++) + total_timecodes += demuxer->titles[i]->timecode_table_size; + +// if(total_timecodes < 3) return 0; + +/* + * // Assign programs based on length of contiguous timecode + * timecode1 = demuxer->titles[current_title]->timecode_table; + * while(!done) + * { + * if(!timecode1) done = 1; + * else + * if(timecode1->end_time - timecode1->start_time < MPEG3_PROGRAM_THRESHOLD) + * { + * // Got interleaved section + * interleaved = 1; + * program_times[0] = timecode1->end_time; + * + * while(interleaved && !done) + * { + * timecode2 = mpeg3demux_next_timecode(demuxer, + * ¤t_title, + * ¤t_timecode, + * 0); + * + * if(!timecode2) done = 1; + * else + * { + * // Another segment of interleaved data + * if(timecode2->end_time - timecode2->start_time < MPEG3_PROGRAM_THRESHOLD) + * { + * // Search program times for where the previous instance of the program left off + * for(program_exists = 0, i = 0; + * i < total_programs && !program_exists; + * i++) + * { + * // Got a previous instance of the program + * if(program_times[i] + 0.5 > timecode2->start_time && + * program_times[i] - 0.5 < timecode2->start_time) + * { + * program_times[i] = timecode2->end_time; + * timecode2->program = i; + * program_exists = 1; + * + * // Programs must always start at 0 for an interleaved section + * if(i < last_program_assigned && i != 0) + * { + * // Shift programs in the interleaved section down until they start at 0 + * for(j = 0; j < total_programs - 1; j++) + * program_times[j] = program_times[j + 1]; + * + * for(previous_title = current_title, previous_timecode = current_timecode; + * titles[previous_title]->timecode_table[previous_timecode].program > 0 && + * (previous_title >= 0 || previous_timecode >= 0); ) + * { + * titles[previous_title]->timecode_table[previous_timecode].program--; + * previous_timecode--; + * if(previous_timecode < 0 && previous_title > 0) + * { + * previous_title--; + * previous_timecode = titles[previous_title]->timecode_table_size - 1; + * } + * } + * } + * } + * } + * + * // Didn't get one + * if(!program_exists) + * { + * program_times[total_programs] = timecode2->end_time; + * timecode2->program = total_programs++; + * } + * last_program_assigned = timecode2->program; + * } + * // No more interleaved section + * else + * { + * interleaved = 0; + * // Restart program table from the beginning + * total_programs = 1; + * last_program_assigned = 0; + * timecode1 = mpeg3demux_next_timecode(demuxer, + * ¤t_title, + * ¤t_timecode, + * 0); + * } + * } + * } + * } + * else + * // Get next timecode + * timecode1 = mpeg3demux_next_timecode(demuxer, + * ¤t_title, + * ¤t_timecode, + * 0); + * } + * + * demuxer->total_programs = total_programs; + */ + +/* Assign absolute timecodes in each program. */ + for(current_program = 0; + current_program < total_programs; + current_program++) + { + current_time = 0; + current_title = 0; + current_timecode = -1; + while(timecode1 = mpeg3demux_next_timecode(demuxer, + ¤t_title, + ¤t_timecode, + current_program)) + { + timecode1->absolute_start_time = current_time; + current_time += timecode1->end_time - timecode1->start_time; + timecode1->absolute_end_time = current_time; + } + } +//for(i = 0; i < demuxer->total_titles; i++) mpeg3_dump_title(demuxer->titles[i]); + demuxer->current_program = 0; + return 0; +} + +/* ==================================================================== */ +/* Entry points */ +/* ==================================================================== */ + +mpeg3_demuxer_t* mpeg3_new_demuxer(mpeg3_t *file, int do_audio, int do_video, int stream_id) +{ + mpeg3_demuxer_t *demuxer = (mpeg3_demuxer_t*)calloc(1, sizeof(mpeg3_demuxer_t)); + int i; + +/* The demuxer will change the default packet size for its own use. */ + demuxer->file = file; + demuxer->packet_size = file->packet_size; + demuxer->do_audio = do_audio; + demuxer->do_video = do_video; + +/* Allocate buffer + padding */ + demuxer->raw_data = (unsigned char*)calloc(1, MPEG3_MAX_PACKSIZE); + demuxer->data_buffer = (unsigned char*)calloc(1, MPEG3_MAX_PACKSIZE); + demuxer->data_allocated = MPEG3_MAX_PACKSIZE; +/* System specific variables */ + demuxer->audio_pid = stream_id; + demuxer->video_pid = stream_id; + demuxer->astream = stream_id; + demuxer->vstream = stream_id; + demuxer->current_title = -1; + return demuxer; +} + +int mpeg3_delete_demuxer(mpeg3_demuxer_t *demuxer) +{ + int i; + + if(demuxer->current_title >= 0) + { + mpeg3io_close_file(demuxer->titles[demuxer->current_title]->fs); + } + + for(i = 0; i < demuxer->total_titles; i++) + { + mpeg3_delete_title(demuxer->titles[i]); + } + + if(demuxer->data_buffer) free(demuxer->data_buffer); + free(demuxer->raw_data); + free(demuxer); +} + +/* Create a title. */ +/* Build a table of timecodes contained in the program stream. */ +/* If toc is 0 just read the first and last timecode. */ +int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, int timecode_search, FILE *toc) +{ + int result = 0, done = 0, counter_start, counter; + mpeg3_t *file = demuxer->file; + long next_byte, prev_byte; + double next_time, prev_time, absolute_time; + long i; + mpeg3_title_t *title; + unsigned long test_header = 0; + mpeg3demux_timecode_t *timecode = 0; + + demuxer->error_flag = 0; + demuxer->generating_timecode = 1; + +/* Create a single title */ + if(!demuxer->total_titles) + { + demuxer->titles[0] = mpeg3_new_title(file, file->fs->path); + demuxer->total_titles = 1; + mpeg3demux_open_title(demuxer, 0); + } + title = demuxer->titles[0]; + title->total_bytes = mpeg3io_total_bytes(title->fs); + + +/* Get the packet size from the file */ + if(file->is_program_stream) + { + mpeg3io_seek(title->fs, 4); + for(i = 0; i < MPEG3_MAX_PACKSIZE && + test_header != MPEG3_PACK_START_CODE; i++) + { + test_header <<= 8; + test_header |= mpeg3io_read_char(title->fs); + } + if(i < MPEG3_MAX_PACKSIZE) demuxer->packet_size = i; + mpeg3io_seek(title->fs, 0); + } + else + demuxer->packet_size = file->packet_size; + +/* Get timecodes for the title */ + if(file->is_transport_stream || file->is_program_stream) + { + mpeg3io_seek(title->fs, 0); + while(!done && !result && !mpeg3io_eof(title->fs)) + { + next_byte = mpeg3io_tell(title->fs); + result = mpeg3_read_next_packet(demuxer); + + if(!result) + { + next_time = demuxer->time; +//printf("%f %f\n", next_time, prev_time); + if(next_time < prev_time || + next_time - prev_time > MPEG3_CONTIGUOUS_THRESHOLD || + !title->timecode_table_size) + { +/* Discontinuous */ + timecode = mpeg3_append_timecode(demuxer, + title, + prev_byte, + prev_time, + next_byte, + next_time, + 0); +/* + * printf("timecode: %ld %ld %f %f\n", + * timecode->start_byte, + * timecode->end_byte, + * timecode->start_time, + * timecode->end_time); + */ + + counter_start = (int)next_time; + } + prev_time = next_time; + prev_byte = next_byte; + counter = (int)next_time; + } + +/* Just get the first bytes if not building a toc to get the stream ID's. */ + if(next_byte > 0x100000 && + (!timecode_search || !toc)) done = 1; + } + +/* Get the last timecode */ + if(!toc || !timecode_search) + { + result = mpeg3io_seek(title->fs, title->total_bytes); + if(!result) result = mpeg3_read_prev_packet(demuxer); + } + + if(title->timecode_table && timecode) + { + timecode->end_byte = title->total_bytes; +// timecode->end_byte = mpeg3io_tell(title->fs)/* + demuxer->packet_size */; + timecode->end_time = demuxer->time; + timecode->absolute_end_time = timecode->end_time - timecode->start_time; + } + } + + mpeg3io_seek(title->fs, 0); + demuxer->generating_timecode = 0; + return 0; +} + +int mpeg3demux_print_timecodes(mpeg3_title_t *title, FILE *output) +{ + mpeg3demux_timecode_t *timecode; + int i; + + if(title->timecode_table) + { + for(i = 0; i < title->timecode_table_size; i++) + { + timecode = &title->timecode_table[i]; + + fprintf(output, "REGION: %ld %ld %f %f\n", + timecode->start_byte, + timecode->end_byte, + timecode->start_time, + timecode->end_time); + } + } + return 0; +} + +/* Read the title information from a toc */ +int mpeg3demux_read_titles(mpeg3_demuxer_t *demuxer) +{ + char string1[MPEG3_STRLEN], string2[MPEG3_STRLEN]; + long start_byte, end_byte; + float start_time, end_time; + mpeg3_title_t *title = 0; + mpeg3_t *file = demuxer->file; + +// Eventually use IFO file to generate titles + while(!feof(file->fs->fd)) + { + fscanf(file->fs->fd, "%s %s %ld %f %f %f", + string1, + string2, + &end_byte, + &start_time, + &end_time); + + if(!strncasecmp(string1, "PATH:", 5)) + { + title = demuxer->titles[demuxer->total_titles++] = mpeg3_new_title(file, string2); + + if(demuxer->current_title < 0) + mpeg3demux_open_title(demuxer, 0); + } + else + if(title) + { + start_byte = atol(string2); + if(!strcasecmp(string1, "REGION:")) + { + mpeg3_append_timecode(demuxer, + title, + 0, + 0, + 0, + 0, + 1); + title->timecode_table[title->timecode_table_size - 1].start_byte = start_byte; + title->timecode_table[title->timecode_table_size - 1].end_byte = end_byte; + title->timecode_table[title->timecode_table_size - 1].start_time = start_time; + title->timecode_table[title->timecode_table_size - 1].end_time = end_time; + } + else + if(!strcasecmp(string1, "ASTREAM:")) + demuxer->astream_table[start_byte] = end_byte; + else + if(!strcasecmp(string1, "VSTREAM:")) + demuxer->vstream_table[start_byte] = end_byte; + else + if(!strcasecmp(string1, "SIZE:")) + title->total_bytes = start_byte; + else + if(!strcasecmp(string1, "PACKETSIZE:")) + demuxer->packet_size = start_byte; + } + } + + mpeg3demux_assign_programs(demuxer); + return 0; +} + +int mpeg3demux_copy_titles(mpeg3_demuxer_t *dst, mpeg3_demuxer_t *src) +{ + long i; + mpeg3_t *file = dst->file; + mpeg3_title_t *dst_title, *src_title; + + dst->packet_size = src->packet_size; + dst->total_titles = src->total_titles; + dst->total_programs = src->total_programs; + for(i = 0; i < MPEG3_MAX_STREAMS; i++) + { + dst->astream_table[i] = src->astream_table[i]; + dst->vstream_table[i] = src->vstream_table[i]; + } + for(i = 0; i < src->total_titles; i++) + { + src_title = src->titles[i]; + dst_title = dst->titles[i] = mpeg3_new_title(file, src->titles[i]->fs->path); + mpeg3_copy_title(dst_title, src_title); + } + + mpeg3demux_open_title(dst, src->current_title); + return 0; +} + +int mpeg3demux_print_streams(mpeg3_demuxer_t *demuxer, FILE *toc) +{ + int i; +/* Print the stream information */ + for(i = 0; i < MPEG3_MAX_STREAMS; i++) + { + if(demuxer->astream_table[i]) + fprintf(toc, "ASTREAM: %d %d\n", i, demuxer->astream_table[i]); + + if(demuxer->vstream_table[i]) + fprintf(toc, "VSTREAM: %d %d\n", i, demuxer->vstream_table[i]); + } + return 0; +} + +/* Need a timecode table to do this */ +double mpeg3demux_length(mpeg3_demuxer_t *demuxer) +{ + mpeg3_title_t *title; + int i, j; + double length; + + for(i = demuxer->total_titles - 1; i >= 0; i--) + { + title = demuxer->titles[i]; + for(j = title->timecode_table_size - 1; j >= 0; j--) + { + if(title->timecode_table[j].program == demuxer->current_program) + { + return title->timecode_table[j].end_time - + title->timecode_table[j].start_time + + title->timecode_table[j].absolute_start_time; + } + } + } + + return 1; +} + +int mpeg3demux_eof(mpeg3_demuxer_t *demuxer) +{ + if(demuxer->current_title >= 0) + { + if(mpeg3io_eof(demuxer->titles[demuxer->current_title]->fs) && + demuxer->current_title >= demuxer->total_titles - 1) + return 1; + } + + return 0; +} + +int mpeg3demux_bof(mpeg3_demuxer_t *demuxer) +{ + if(demuxer->current_title >= 0) + { + if(mpeg3io_bof(demuxer->titles[demuxer->current_title]->fs) && + demuxer->current_title <= 0) + return 1; + } + return 0; +} + + +/* For elemental streams seek to a byte */ +int mpeg3demux_seek_byte(mpeg3_demuxer_t *demuxer, long byte) +{ + long current_position; + mpeg3_t *file = demuxer->file; + mpeg3_title_t *title = demuxer->titles[demuxer->current_title]; + + demuxer->data_position = 0; + demuxer->data_size = 0; + + demuxer->error_flag = mpeg3io_seek(title->fs, byte); + + if(!demuxer->error_flag && (file->is_transport_stream || file->is_program_stream)) + { +/* Get on a packet boundary only for system streams. */ + current_position = mpeg3io_tell(title->fs); + if(byte % demuxer->packet_size) + { + demuxer->error_flag |= mpeg3io_seek(title->fs, current_position - (current_position % demuxer->packet_size)); + } + } + return demuxer->error_flag; +} + +/* For programs streams and toc seek to a time */ +int mpeg3demux_seek_time(mpeg3_demuxer_t *demuxer, double new_time) +{ + int i, j, done = 0, result = 0; + double byte_offset, new_byte_offset; + double guess = 0, minimum = 65535; + mpeg3_title_t *title; + mpeg3demux_timecode_t *timecode; + + demuxer->error_flag = 0; + + i = 0; + j = 0; + title = demuxer->titles[i]; + timecode = &title->timecode_table[j]; + +/* Get the title and timecode of the new position */ + while(!demuxer->error_flag && + !(timecode->absolute_start_time <= new_time && + timecode->absolute_end_time > new_time && + timecode->program == demuxer->current_program)) + { +/* Next timecode */ + j++; + if(j >= title->timecode_table_size) + { + i++; + j = 0; + if(i >= demuxer->total_titles) + { + demuxer->error_flag = 1; + return 1; + } + else + { + mpeg3demux_open_title(demuxer, i); + } + } + + title = demuxer->titles[i]; + timecode = &title->timecode_table[j]; + } + +/* Guess the new byte position */ + demuxer->current_timecode = j; + + byte_offset = ((new_time - timecode->absolute_start_time) / + (timecode->absolute_end_time - timecode->absolute_start_time) * + (timecode->end_byte - timecode->start_byte) + + timecode->start_byte); +//printf("mpeg3demux_seek_time %f %f\n", new_time, byte_offset); + + while(!done && !result && byte_offset >= 0) + { + result = mpeg3demux_seek_byte(demuxer, (long)byte_offset); +//printf("seek_time 0 byte %.0f want %f result %d\n", byte_offset, new_time, result); + + if(!result) + { + result = mpeg3_read_next_packet(demuxer); +// printf("seek_time 1 guess %f want %f\n", guess, new_time); + guess = demuxer->time + demuxer->time_offset; + + if(fabs(new_time - guess) >= fabs(minimum)) done = 1; + else + { + minimum = guess - new_time; + new_byte_offset = byte_offset + ((new_time - guess) / + (timecode->end_time - timecode->start_time) * + (timecode->end_byte - timecode->start_byte)); + if(labs((long)new_byte_offset - (long)byte_offset) < demuxer->packet_size) done = 1; + byte_offset = new_byte_offset; + } + } + } + +/* Get one packet before the packet just read */ + if(!result && byte_offset > demuxer->packet_size && minimum > 0) + { + mpeg3_read_prev_packet(demuxer); + mpeg3_read_prev_packet(demuxer); + } +//printf("seek_time %d %d %d\n", demuxer->current_title, demuxer->current_timecode, mpeg3demux_tell(demuxer)); + demuxer->error_flag = result; + return result; +} + +int mpeg3demux_seek_percentage(mpeg3_demuxer_t *demuxer, double percentage) +{ + double total_bytes = 0; + double absolute_position; + long relative_position; + int i, new_title; + mpeg3_title_t *title; + + demuxer->error_flag = 0; + +/* Get the absolute byte position; */ + for(i = 0; i < demuxer->total_titles; i++) + total_bytes += demuxer->titles[i]->total_bytes; + + absolute_position = percentage * total_bytes; + +/* Get the title the byte is inside */ + for(new_title = 0, total_bytes = 0; new_title < demuxer->total_titles; new_title++) + { + total_bytes += demuxer->titles[new_title]->total_bytes; + if(absolute_position < total_bytes) break; + } + + if(new_title >= demuxer->total_titles) + { + new_title = demuxer->total_titles - 1; + } + +/* Got a title */ + title = demuxer->titles[new_title]; + total_bytes -= title->total_bytes; + relative_position = (long)(absolute_position - total_bytes); + +/* Get the timecode the byte is inside */ + for(demuxer->current_timecode = 0; + demuxer->current_timecode < title->timecode_table_size; + demuxer->current_timecode++) + { + if(title->timecode_table[demuxer->current_timecode].start_byte <= relative_position && + title->timecode_table[demuxer->current_timecode].end_byte > relative_position) + { + break; + } + } + + if(demuxer->current_timecode >= title->timecode_table_size) + demuxer->current_timecode = title->timecode_table_size - 1; + +/* Get the nearest timecode in the same program */ + while(demuxer->current_timecode < title->timecode_table_size - 1 && + title->timecode_table[demuxer->current_timecode].program != demuxer->current_program) + { + demuxer->current_timecode++; + } + +/* Open the new title and seek to the correct byte */ + if(new_title != demuxer->current_title) + { + demuxer->error_flag = mpeg3demux_open_title(demuxer, new_title); + } + + if(!demuxer->error_flag) + demuxer->error_flag = mpeg3io_seek(title->fs, relative_position); + + return demuxer->error_flag; +} + +double mpeg3demux_tell_percentage(mpeg3_demuxer_t *demuxer) +{ + double total_bytes = 0; + double position = 0; + int i; + + demuxer->error_flag = 0; + position = mpeg3io_tell(demuxer->titles[demuxer->current_title]->fs); + for(i = 0; i < demuxer->total_titles; i++) + { + if(i == demuxer->current_title) + { + position += total_bytes; + } + total_bytes += demuxer->titles[i]->total_bytes; + } + return position / total_bytes; +} + +double mpeg3demux_get_time(mpeg3_demuxer_t *demuxer) +{ + return demuxer->time; +} + +long mpeg3demux_tell(mpeg3_demuxer_t *demuxer) +{ + return mpeg3io_tell(demuxer->titles[demuxer->current_title]->fs); +} + +long mpeg3demuxer_total_bytes(mpeg3_demuxer_t *demuxer) +{ + mpeg3_title_t *title = demuxer->titles[demuxer->current_title]; + return title->total_bytes; +} + +mpeg3_demuxer_t* mpeg3_get_demuxer(mpeg3_t *file) +{ + if(file->is_program_stream || file->is_transport_stream) + { + if(file->has_audio) return file->atrack[0]->demuxer; + else + if(file->has_video) return file->vtrack[0]->demuxer; + } + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3demux.h b/core/multimedia/opieplayer/libmpeg3/mpeg3demux.h new file mode 100644 index 0000000..9dfd182 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3demux.h @@ -0,0 +1,118 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3DEMUX_H +#define MPEG3DEMUX_H + +#include "mpeg3title.h" +#include + +typedef struct +{ + struct mpeg3_rec* file; +/* Data consisting of the multiplexed packet */ + unsigned char *raw_data; + long raw_offset; + int raw_size; + long packet_size; +/* Only one is on depending on which track owns the demultiplexer. */ + int do_audio; + int do_video; +/* Data consisting of the elementary stream */ + unsigned char *data_buffer; + long data_size; + long data_position; + long data_allocated; +/* Remember when the file descriptor is at the beginning of the packet just read. */ + int reverse; +/* Set to 1 when eof or attempt to read before beginning */ + int error_flag; +/* Temp variables for returning */ + unsigned char next_char; +/* Correction factor for time discontinuity */ + double time_offset; + int generating_timecode; + +/* Titles */ + mpeg3_title_t *titles[MPEG3_MAX_STREAMS]; + int total_titles; + int current_title; + +/* Tables of every stream ID encountered */ + int astream_table[MPEG3_MAX_STREAMS]; /* macro of audio format if audio */ + int vstream_table[MPEG3_MAX_STREAMS]; /* 1 if video */ + +/* Programs */ + int total_programs; + int current_program; + +/* Timecode in the current title */ + int current_timecode; + +/* Byte position in the current title */ + long current_byte; + + int transport_error_indicator; + int payload_unit_start_indicator; + int pid; + int transport_scrambling_control; + int adaptation_field_control; + int continuity_counter; + int is_padding; + int pid_table[MPEG3_PIDMAX]; + int continuity_counters[MPEG3_PIDMAX]; + int total_pids; + int adaptation_fields; + double time; /* Time in seconds */ + int audio_pid; + int video_pid; + int astream; /* Video stream ID being decoded. -1 = select first ID in stream */ + int vstream; /* Audio stream ID being decoded. -1 = select first ID in stream */ + int aformat; /* format of the audio derived from multiplexing codes */ + long program_association_tables; + int table_id; + int section_length; + int transport_stream_id; + long pes_packets; + double pes_audio_time; /* Presentation Time stamps */ + double pes_video_time; /* Presentation Time stamps */ +} mpeg3_demuxer_t; + +/* ========================================================================= */ +/* Entry points */ +/* ========================================================================= */ + +#define mpeg3demux_error(demuxer) (((mpeg3_demuxer_t *)(demuxer))->error_flag) + +#define mpeg3demux_time_offset(demuxer) (((mpeg3_demuxer_t *)(demuxer))->time_offset) + +#define mpeg3demux_current_time(demuxer) (((mpeg3_demuxer_t *)(demuxer))->time + ((mpeg3_demuxer_t *)(demuxer))->time_offset) + +#define mpeg3demux_read_char(demuxer) \ + ((((mpeg3_demuxer_t *)(demuxer))->data_position < ((mpeg3_demuxer_t *)(demuxer))->data_size) ? \ + ((mpeg3_demuxer_t *)(demuxer))->data_buffer[((mpeg3_demuxer_t *)(demuxer))->data_position++] : \ + mpeg3demux_read_char_packet(demuxer)) + +#define mpeg3demux_read_prev_char(demuxer) \ + ((((mpeg3_demuxer_t *)(demuxer))->data_position != 0) ? \ + ((mpeg3_demuxer_t *)(demuxer))->data_buffer[((mpeg3_demuxer_t *)(demuxer))->data_position--] : \ + mpeg3demux_read_prev_char_packet(demuxer)) + + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3io.c b/core/multimedia/opieplayer/libmpeg3/mpeg3io.c new file mode 100644 index 0000000..c5807a7 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3io.c @@ -0,0 +1,127 @@ +#include "mpeg3private.h" +#include "mpeg3protos.h" + +#ifndef _WIN32 +#include +#else + +#endif +#include +#include +#include + +mpeg3_fs_t* mpeg3_new_fs(char *path) +{ + mpeg3_fs_t *fs = (mpeg3_fs_t*)calloc(1, sizeof(mpeg3_fs_t)); + fs->css = mpeg3_new_css(); + strcpy(fs->path, path); + return fs; +} + +int mpeg3_delete_fs(mpeg3_fs_t *fs) +{ + mpeg3_delete_css(fs->css); + free(fs); + return 0; +} + +int mpeg3_copy_fs(mpeg3_fs_t *dst, mpeg3_fs_t *src) +{ + strcpy(dst->path, src->path); + dst->current_byte = 0; + return 0; +} + +long mpeg3io_get_total_bytes(mpeg3_fs_t *fs) +{ +/* + * struct stat st; + * if(stat(fs->path, &st) < 0) return 0; + * return (long)st.st_size; + */ + + fseek(fs->fd, 0, SEEK_END); + fs->total_bytes = ftell(fs->fd); + fseek(fs->fd, 0, SEEK_SET); + return fs->total_bytes; +} + +int mpeg3io_open_file(mpeg3_fs_t *fs) +{ +/* Need to perform authentication before reading a single byte. */ + mpeg3_get_keys(fs->css, fs->path); + + if(!(fs->fd = fopen(fs->path, "rb"))) + { + perror("mpeg3io_open_file"); + return 1; + } + + fs->total_bytes = mpeg3io_get_total_bytes(fs); + + if(!fs->total_bytes) + { + fclose(fs->fd); + return 1; + } + fs->current_byte = 0; + return 0; +} + +int mpeg3io_close_file(mpeg3_fs_t *fs) +{ + if(fs->fd) fclose(fs->fd); + fs->fd = 0; + return 0; +} + +int mpeg3io_read_data(unsigned char *buffer, long bytes, mpeg3_fs_t *fs) +{ + int result = 0; +//printf("read %d bytes\n",bytes); + result = !fread(buffer, 1, bytes, fs->fd); + fs->current_byte += bytes; + return (result && bytes); +} + +int mpeg3io_device(char *path, char *device) +{ + struct stat file_st, device_st; + struct mntent *mnt; + FILE *fp; + + if(stat(path, &file_st) < 0) + { + perror("mpeg3io_device"); + return 1; + } + +#ifndef _WIN32 + fp = setmntent(MOUNTED, "r"); + while(fp && (mnt = getmntent(fp))) + { + if(stat(mnt->mnt_fsname, &device_st) < 0) continue; + if(device_st.st_rdev == file_st.st_dev) + { + strncpy(device, mnt->mnt_fsname, MPEG3_STRLEN); + break; + } + } + endmntent(fp); +#endif + + return 0; +} + +int mpeg3io_seek(mpeg3_fs_t *fs, long byte) +{ + fs->current_byte = byte; + return fseek(fs->fd, byte, SEEK_SET); +} + +int mpeg3io_seek_relative(mpeg3_fs_t *fs, long bytes) +{ + fs->current_byte += bytes; + return fseek(fs->fd, fs->current_byte, SEEK_SET); +} + diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3io.h b/core/multimedia/opieplayer/libmpeg3/mpeg3io.h new file mode 100644 index 0000000..092e411 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3io.h @@ -0,0 +1,74 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3IO_H +#define MPEG3IO_H + + +#include +#include "mpeg3css.h" +#include "mpeg3private.inc" + +/* Filesystem structure */ + +typedef struct +{ + FILE *fd; + mpeg3_css_t *css; /* Encryption object */ + char path[MPEG3_STRLEN]; +/* Hypothetical position of file pointer */ + long current_byte; + long total_bytes; +} mpeg3_fs_t; + +#define mpeg3io_tell(fs) (((mpeg3_fs_t *)(fs))->current_byte) + +// End of file +#define mpeg3io_eof(fs) (((mpeg3_fs_t *)(fs))->current_byte >= ((mpeg3_fs_t *)(fs))->total_bytes) + +// Beginning of file +#define mpeg3io_bof(fs) (((mpeg3_fs_t *)(fs))->current_byte < 0) + + +#define mpeg3io_total_bytes(fs) (((mpeg3_fs_t *)(fs))->total_bytes) + +extern inline unsigned int mpeg3io_read_int32(mpeg3_fs_t *fs) +{ + int a, b, c, d; + unsigned int result; +/* Do not fread. This breaks byte ordering. */ + a = (unsigned char)fgetc(fs->fd); + b = (unsigned char)fgetc(fs->fd); + c = (unsigned char)fgetc(fs->fd); + d = (unsigned char)fgetc(fs->fd); + result = ((int)a << 24) | + ((int)b << 16) | + ((int)c << 8) | + ((int)d); + fs->current_byte += 4; + return result; +} + +extern inline unsigned int mpeg3io_read_char(mpeg3_fs_t *fs) +{ + fs->current_byte++; + return fgetc(fs->fd); +} + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3private.h b/core/multimedia/opieplayer/libmpeg3/mpeg3private.h new file mode 100644 index 0000000..f0e11aa --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3private.h @@ -0,0 +1,62 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3PRIVATE_H +#define MPEG3PRIVATE_H + +#include "mpeg3atrack.h" +#include "mpeg3css.h" +#include "mpeg3io.h" +#include "mpeg3private.inc" +#include "mpeg3title.h" +#include "mpeg3vtrack.h" + +struct mpeg3_rec +{ + mpeg3_fs_t *fs; /* Store entry path here */ + mpeg3_demuxer_t *demuxer; /* Master tables */ + +/* Media specific */ + int has_audio; + int has_video; + int total_astreams; + int total_vstreams; + mpeg3_atrack_t *atrack[MPEG3_MAX_STREAMS]; + mpeg3_vtrack_t *vtrack[MPEG3_MAX_STREAMS]; + +/* Only one of these is set to 1 to specify what kind of stream we have. */ + int is_transport_stream; + int is_program_stream; + int is_audio_stream; /* Elemental stream */ + int is_video_stream; /* Elemental stream */ + long packet_size; +/* Type and stream for getting current percentage */ + int last_type_read; /* 1 - audio 2 - video */ + int last_stream_read; + + int program; /* Number of program to play */ + int cpus; + int have_mmx; +}; + +typedef struct mpeg3_rec mpeg3_t; + + + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3private.inc b/core/multimedia/opieplayer/libmpeg3/mpeg3private.inc new file mode 100644 index 0000000..7e56e7f --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3private.inc @@ -0,0 +1,110 @@ +#ifndef LIBMPEG3_INC +#define LIBMPEG3_INC + +#ifdef _WIN32 + +// Disable some compiler warnings that happen a lot but don't matter +#pragma warning( disable : 4003 ) // not enough parameters for macro +#pragma warning( disable : 4305 ) // truncation frm double to float +#pragma warning( disable : 4715 ) // not all control paths return a value +#pragma warning( disable : 4716 ) // must return a value + +#ifdef LIBMPEG_EXPORTS +#define LIBMPEG_EXPORT __declspec( dllexport ) +#else +#define LIBMPEG_EXPORT __declspec( dllimport ) +#endif + +#ifdef ERROR +#undef ERROR +#include +#undef ERROR +#define ERROR (-1) +#else +#include +#undef ERROR +#endif + +#define inline __inline +#define M_PI 3.14159265358979323846 +#define M_SQRT2 1.41421356237309504880 + +#define pthread_mutexattr_t int +#define pthread_mutexattr_init(a) // Nothing +#define pthread_mutex_t CRITICAL_SECTION +#define pthread_mutex_init(a,b) InitializeCriticalSection(a) +#define pthread_mutex_lock(a) EnterCriticalSection(a) +#define pthread_mutex_unlock(a) LeaveCriticalSection(a) +#define pthread_mutex_destroy(a) //DeleteCriticalSection(a) + +#define pthread_attr_t int +#define pthread_attr_init(a) // Nothing +#define pthread_t unsigned long +#define pthread_create(a,b,c,d) *(a) = _beginthread(c,0,d) +//#define pthread_join(a,b) _endthread(b) +//#define pthread_join(a,b) _cwait(NULL,b,NULL) +#define pthread_join(a,b) + +#define strncasecmp(a,b,c) _strnicmp(a,b,c) +#define strcasecmp(a,b) _stricmp(a,b) +#define bzero(a,b) memset(a,0,b) + +#else + +#define LONGLONG long long +#define ULONGLONG unsigned long long + +#endif + +#ifndef LIBMPEG_EXPORT +#define LIBMPEG_EXPORT +#endif + +#define MPEG3_FLOAT32 mpeg3_real_t +#define MPEG3_INT16 short int +#define MPEG3_INT32 int +#define MPEG3_INT64 long + +#define MPEG3_TOC_PREFIX 0x544f4356 +#define MPEG3_TOC_PREFIXLOWER 0x746f6376 +#define MPEG3_ID3_PREFIX 0x494433 +#define MPEG3_RIFF_CODE 0x52494646 +#define MPEG3_PROC_CPUINFO "/proc/cpuinfo" +#define MPEG3_TS_PACKET_SIZE 188 +#define MPEG3_DVD_PACKET_SIZE 0x800 +#define MPEG3_SYNC_BYTE 0x47 +#define MPEG3_PACK_START_CODE 0x000001ba +#define MPEG3_SEQUENCE_START_CODE 0x000001b3 +#define MPEG3_SEQUENCE_END_CODE 0x000001b7 +#define MPEG3_SYSTEM_START_CODE 0x000001bb +#define MPEG3_STRLEN 1024 +#define MPEG3_PIDMAX 20 /* Maximum number of PIDs in one stream */ +#define MPEG3_PROGRAM_ASSOCIATION_TABLE 0x00 +#define MPEG3_CONDITIONAL_ACCESS_TABLE 0x01 +#define MPEG3_PACKET_START_CODE_PREFIX 0x000001 +#define MPEG3_PRIVATE_STREAM_2 0xbf +#define MPEG3_PADDING_STREAM 0xbe +#define MPEG3_GOP_START_CODE 0x000001b8 +#define MPEG3_PICTURE_START_CODE 0x00000100 +#define MPEG3_EXT_START_CODE 0x000001b5 +#define MPEG3_USER_START_CODE 0x000001b2 +#define MPEG3_SLICE_MIN_START 0x00000101 +#define MPEG3_SLICE_MAX_START 0x000001af +#define MPEG3_AC3_START_CODE 0x0b77 +#define MPEG3_PCM_START_CODE 0x0180 +#define MPEG3_MAX_CPUS 256 +#define MPEG3_MAX_STREAMS 256 +#define MPEG3_MAX_PACKSIZE 262144 +#define MPEG3_CONTIGUOUS_THRESHOLD 10 /* Positive difference before declaring timecodes discontinuous */ +#define MPEG3_PROGRAM_THRESHOLD 5 /* Minimum number of seconds before interleaving programs */ +#define MPEG3_SEEK_THRESHOLD 16 /* Number of frames difference before absolute seeking */ + +/* Values for audio format */ +#define AUDIO_UNKNOWN 0 +#define AUDIO_MPEG 1 +#define AUDIO_AC3 2 +#define AUDIO_PCM 3 +#define AUDIO_AAC 4 +#define AUDIO_JESUS 5 + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3protos.h b/core/multimedia/opieplayer/libmpeg3/mpeg3protos.h new file mode 100644 index 0000000..631336b --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3protos.h @@ -0,0 +1,278 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3PROTOS_H +#define MPEG3PROTOS_H + +#if defined(__cplusplus) +extern "C" { +#endif + +/* CSS */ + +mpeg3_css_t* mpeg3_new_css(); + +/* DEMUX */ + +mpeg3_demuxer_t* mpeg3_new_demuxer(mpeg3_t *file, int do_audio, int do_video, int stream_id); +int mpeg3_delete_demuxer(mpeg3_demuxer_t *demuxer); +int mpeg3demux_read_data(mpeg3_demuxer_t *demuxer, unsigned char *output, long size); +unsigned int mpeg3demux_read_int32(mpeg3_demuxer_t *demuxer); +unsigned int mpeg3demux_read_int24(mpeg3_demuxer_t *demuxer); +unsigned int mpeg3demux_read_int16(mpeg3_demuxer_t *demuxer); +double mpeg3demux_length(mpeg3_demuxer_t *demuxer); +mpeg3_demuxer_t* mpeg3_get_demuxer(mpeg3_t *file); +long mpeg3demux_tell(mpeg3_demuxer_t *demuxer); +double mpeg3demux_tell_percentage(mpeg3_demuxer_t *demuxer); +double mpeg3demux_get_time(mpeg3_demuxer_t *demuxer); +int mpeg3demux_eof(mpeg3_demuxer_t *demuxer); +int mpeg3demux_bof(mpeg3_demuxer_t *demuxer); +int mpeg3demux_copy_titles(mpeg3_demuxer_t *dst, mpeg3_demuxer_t *src); +int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, int timecode_search, FILE *toc); +long mpeg3demuxer_total_bytes(mpeg3_demuxer_t *demuxer); +int mpeg3demux_seek_byte(mpeg3_demuxer_t *demuxer, long byte); +int mpeg3demux_seek_time(mpeg3_demuxer_t *demuxer, double new_time); +int mpeg3demux_seek_percentage(mpeg3_demuxer_t *demuxer, double percentage); +int mpeg3demux_print_streams(mpeg3_demuxer_t *demuxer, FILE *toc); +int mpeg3demux_print_timecodes(mpeg3_title_t *title, FILE *output); +int mpeg3demux_read_titles(mpeg3_demuxer_t *demuxer); +int mpeg3demux_open_title(mpeg3_demuxer_t *demuxer, int title_number); + +/* TITLE */ + +mpeg3_title_t* mpeg3_new_title(mpeg3_t *file, char *path); +int mpeg3_delete_title(mpeg3_title_t *title); +int mpeg3_copy_title(mpeg3_title_t *dst, mpeg3_title_t *src); + + +/* ATRACK */ + +mpeg3_atrack_t* mpeg3_new_atrack(mpeg3_t *file, int stream_id, int is_ac3, mpeg3_demuxer_t *demuxer); +int mpeg3_delete_atrack(mpeg3_t *file, mpeg3_atrack_t *atrack); + +/* VTRACK */ + +mpeg3_vtrack_t* mpeg3_new_vtrack(mpeg3_t *file, int stream_id, mpeg3_demuxer_t *demuxer); +int mpeg3_delete_vtrack(mpeg3_t *file, mpeg3_vtrack_t *vtrack); + +/* AUDIO */ +mpeg3audio_t* mpeg3audio_new(mpeg3_t *file, mpeg3_atrack_t *track, int is_ac3); +int mpeg3audio_delete(mpeg3audio_t *audio); +int mpeg3audio_seek_sample(mpeg3audio_t *audio, long sample); +int mpeg3audio_seek_percentage(mpeg3audio_t *audio, double percentage); +int mpeg3audio_decode_audio(mpeg3audio_t *audio, + mpeg3_real_t *output_f, + short *output_i, int sampleSpacing, + int channel, + long start_position, + long len); +int mpeg3audio_read_raw(mpeg3audio_t *audio, unsigned char *output, long *size, long max_size); +int mpeg3audio_read_ac3_header(mpeg3audio_t *audio); +int mpeg3audio_read_pcm_header(mpeg3audio_t *audio); +int mpeg3audio_synth_mono(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, mpeg3_real_t *samples, int *pnt); +int mpeg3audio_synth_stereo(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, int channel, mpeg3_real_t *out, int *pnt); +int mpeg3audio_replace_buffer(mpeg3audio_t *audio, long new_allocation); +int mpeg3audio_ac3_exponent_unpack(mpeg3audio_t *audio, + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk); +int mpeg3audio_ac3_bit_allocate(mpeg3audio_t *audio, + unsigned int fscod, + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk); +int mpeg3audio_ac3_coeff_unpack(mpeg3audio_t *audio, + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk, + mpeg3ac3_stream_samples_t samples); +int mpeg3audio_ac3_imdct(mpeg3audio_t *audio, + mpeg3_ac3bsi_t *bsi, + mpeg3_ac3audblk_t *audblk, + mpeg3ac3_stream_samples_t samples); +int mpeg3audio_replace_buffer(mpeg3audio_t *audio, long new_allocation); +int mpeg3audio_dct36(mpeg3_real_t *inbuf, mpeg3_real_t *o1, mpeg3_real_t *o2, mpeg3_real_t *wintab, mpeg3_real_t *tsbuf); +int mpeg3audio_dct12(mpeg3_real_t *in,mpeg3_real_t *rawout1,mpeg3_real_t *rawout2,register mpeg3_real_t *wi,register mpeg3_real_t *ts); +int mpeg3audio_read_header(mpeg3audio_t *audio); +int mpeg3audio_do_ac3(mpeg3audio_t *audio); +int mpeg3audio_dolayer2(mpeg3audio_t *audio); +int mpeg3audio_dolayer3(mpeg3audio_t *audio); +int mpeg3audio_do_pcm(mpeg3audio_t *audio); +int mpeg3audio_dct64(mpeg3_real_t *a, mpeg3_real_t *b, mpeg3_real_t *c); +int mpeg3audio_reset_synths(mpeg3audio_t *audio); +int mpeg3audio_prev_header(mpeg3audio_t *audio); +int mpeg3audio_read_layer3_frame(mpeg3audio_t *audio); +int mpeg3audio_new_decode_tables(mpeg3audio_t *audio); +int mpeg3audio_imdct_init(mpeg3audio_t *audio); + + +/* VIDEO */ +mpeg3video_t* mpeg3video_new(mpeg3_t *file, mpeg3_vtrack_t *track); +int mpeg3video_delete(mpeg3video_t *video); +int mpeg3video_read_frame(mpeg3video_t *video, + long frame_number, + unsigned char **output_rows, + int in_x, + int in_y, + int in_w, + int in_h, + int out_w, + int out_h, + int color_model); +int mpeg3video_set_cpus(mpeg3video_t *video, int cpus); +int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx); +int mpeg3video_seek(mpeg3video_t *video); +int mpeg3video_seek_frame(mpeg3video_t *video, long frame); +int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage); +int mpeg3video_previous_frame(mpeg3video_t *video); +int mpeg3video_drop_frames(mpeg3video_t *video, long frames); +int mpeg3video_read_yuvframe(mpeg3video_t *video, + long frame_number, + char *y_output, + char *u_output, + char *v_output, + int in_x, + int in_y, + int in_w, + int in_h); +int mpeg3video_read_raw(mpeg3video_t *video, unsigned char *output, long *size, long max_size); +int mpeg3video_display_second_field(mpeg3video_t *video); +int mpeg3video_init_output(); +int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat); +int mpeg3video_getpicture(mpeg3video_t *video, int framenum); +int mpeg3video_match_refframes(mpeg3video_t *video); +int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code); +int mpeg3video_prev_code(mpeg3_bits_t* stream, unsigned int code); +int mpeg3video_getgophdr(mpeg3video_t *video); +int mpeg3video_present_frame(mpeg3video_t *video); +int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes); +int mpeg3video_getslicehdr(mpeg3_slice_t *slice, mpeg3video_t *video); +int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice); +int mpeg3video_macroblock_modes(mpeg3_slice_t *slice, + mpeg3video_t *video, + int *pmb_type, + int *pstwtype, + int *pstwclass, + int *pmotion_type, + int *pmv_count, + int *pmv_format, + int *pdmv, + int *pmvscale, + int *pdct_type); +int mpeg3video_motion_vectors(mpeg3_slice_t *slice, + mpeg3video_t *video, + int PMV[2][2][2], + int dmvector[2], + int mv_field_sel[2][2], + int s, + int mv_count, + int mv_format, + int h_r_size, + int v_r_size, + int dmv, + int mvscale); +void mpeg3video_motion_vector(mpeg3_slice_t *slice, + mpeg3video_t *video, + int *PMV, + int *dmvector, + int h_r_size, + int v_r_size, + int dmv, + int mvscale, + int full_pel_vector); +int mpeg3video_get_cbp(mpeg3_slice_t *slice); +int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size); +int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice, + mpeg3video_t *video, + int comp, + int dc_dct_pred[]); +int mpeg3video_getintrablock(mpeg3_slice_t *slice, + mpeg3video_t *video, + int comp, + int dc_dct_pred[]); +int mpeg3video_getmpg2interblock(mpeg3_slice_t *slice, + mpeg3video_t *video, + int comp); +int mpeg3video_getinterblock(mpeg3_slice_t *slice, + mpeg3video_t *video, + int comp); +int mpeg3video_reconstruct(mpeg3video_t *video, + int bx, + int by, + int mb_type, + int motion_type, + int PMV[2][2][2], + int mv_field_sel[2][2], + int dmvector[2], + int stwtype); +void mpeg3video_calc_dmv(mpeg3video_t *video, + int DMV[][2], + int *dmvector, + int mvx, + int mvy); + + +/* FILESYSTEM */ + +mpeg3_fs_t* mpeg3_new_fs(char *path); +int mpeg3_delete_fs(mpeg3_fs_t *fs); +int mpeg3io_open_file(mpeg3_fs_t *fs); +int mpeg3io_close_file(mpeg3_fs_t *fs); +int mpeg3io_read_data(unsigned char *buffer, long bytes, mpeg3_fs_t *fs); + +/* BITSTREAM */ +mpeg3_bits_t* mpeg3bits_new_stream(mpeg3_t *file, mpeg3_demuxer_t *demuxer); +unsigned int mpeg3bits_getbits(mpeg3_bits_t* stream, int n); +int mpeg3bits_read_buffer(mpeg3_bits_t* stream, unsigned char *buffer, int bytes); +int mpeg3bits_use_ptr(mpeg3_bits_t* stream, unsigned char *buffer); +int mpeg3bits_use_demuxer(mpeg3_bits_t* stream); +int mpeg3bits_refill(mpeg3_bits_t* stream); +int mpeg3bits_getbitoffset(mpeg3_bits_t *stream); +void mpeg3bits_start_reverse(mpeg3_bits_t* stream); +void mpeg3bits_start_forward(mpeg3_bits_t* stream); +int mpeg3bits_delete_stream(mpeg3_bits_t* stream); +int mpeg3bits_byte_align(mpeg3_bits_t *stream); +int mpeg3bits_seek_start(mpeg3_bits_t* stream); +int mpeg3bits_seek_time(mpeg3_bits_t* stream, double time_position); +int mpeg3bits_seek_byte(mpeg3_bits_t* stream, long position); +int mpeg3bits_seek_percentage(mpeg3_bits_t* stream, double percentage); +unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream); +int mpeg3bits_seek_end(mpeg3_bits_t* stream); + +/* MISC */ +int mpeg3_read_toc(mpeg3_t *file); +int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams); +int mpeg3_mmx_test(); +int mpeg3io_seek(mpeg3_fs_t *fs, long byte); +int mpeg3io_seek_relative(mpeg3_fs_t *fs, long bytes); +int mpeg3io_device(char *path, char *device); +int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector); +int mpeg3_delete_css(mpeg3_css_t *css); +int mpeg3_get_keys(mpeg3_css_t *css, char *path); +int mpeg3_copy_fs(mpeg3_fs_t *dst, mpeg3_fs_t *src); +int mpeg3_min(int x, int y); +int mpeg3_max(int x, int y); +int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer); +int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer); +int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice); +int mpeg3_new_slice_decoder(mpeg3video_t *video, mpeg3_slice_t *slice); +int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3title.c b/core/multimedia/opieplayer/libmpeg3/mpeg3title.c new file mode 100644 index 0000000..0c93363 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3title.c @@ -0,0 +1,63 @@ +#include "mpeg3private.h" +#include "mpeg3protos.h" +#include "mpeg3title.h" + + +#include + + +mpeg3_title_t* mpeg3_new_title(mpeg3_t *file, char *path) +{ + mpeg3_title_t *title = (mpeg3_title_t*)calloc(1, sizeof(mpeg3_title_t)); + title->fs = mpeg3_new_fs(path); + title->file = file; + return title; +} + +int mpeg3_delete_title(mpeg3_title_t *title) +{ + mpeg3_delete_fs(title->fs); + if(title->timecode_table_size) + { + free(title->timecode_table); + } + free(title); + return 0; +} + + +int mpeg3_copy_title(mpeg3_title_t *dst, mpeg3_title_t *src) +{ + int i; + + mpeg3_copy_fs(dst->fs, src->fs); + dst->total_bytes = src->total_bytes; + + if(src->timecode_table_size) + { + dst->timecode_table_allocation = src->timecode_table_allocation; + dst->timecode_table_size = src->timecode_table_size; + dst->timecode_table = (mpeg3demux_timecode_t*)calloc(1, sizeof(mpeg3demux_timecode_t) * dst->timecode_table_allocation); + + for(i = 0; i < dst->timecode_table_size; i++) + { + dst->timecode_table[i] = src->timecode_table[i]; + } + } +} + +int mpeg3_dump_title(mpeg3_title_t *title) +{ + int i; + + for(i = 0; i < title->timecode_table_size; i++) + { + printf("%f: %d - %d %f %f %d\n", + title->timecode_table[i].absolute_start_time, + title->timecode_table[i].start_byte, + title->timecode_table[i].end_byte, + title->timecode_table[i].start_time, + title->timecode_table[i].end_time, + title->timecode_table[i].program); + } +} diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3title.h b/core/multimedia/opieplayer/libmpeg3/mpeg3title.h new file mode 100644 index 0000000..a853217 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3title.h @@ -0,0 +1,47 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3TITLE_H +#define MPEG3TITLE_H + +#include "mpeg3io.h" + +typedef struct +{ + long start_byte; + double start_time; + double absolute_start_time; + double absolute_end_time; + long end_byte; + double end_time; + int program; +} mpeg3demux_timecode_t; + +typedef struct +{ + struct mpeg3_rec *file; + mpeg3_fs_t *fs; + long total_bytes; /* Total bytes in file. Critical for seeking and length. */ +/* Timecode table */ + mpeg3demux_timecode_t *timecode_table; + long timecode_table_size; /* Number of entries */ + long timecode_table_allocation; /* Number of available slots */ +} mpeg3_title_t; + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3toc.c b/core/multimedia/opieplayer/libmpeg3/mpeg3toc.c new file mode 100644 index 0000000..84b31cb --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3toc.c @@ -0,0 +1,81 @@ +#include "libmpeg3.h" +#include "mpeg3protos.h" + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int i; +/* FILE *output; */ + char new_path[1024], *ext; + struct stat st; + long size; + int timecode_search = 0; + + if(argc < 2) + { + fprintf(stderr, "Create a table of contents for a DVD.\n" + " Usage: mpeg3toc [-t] ...\n" + " -t Perform timecode search.\n" + "\n" + " The filenames should be absolute paths unless you plan\n" + " to always run your movie player from the same directory\n" + " as the filename. Alternatively you can edit the toc by\n" + " hand.\n" + " The timecode search allows XMovie to play the Matrix.\n" + "Example: mpeg3toc /cd2/video_ts/vts_01_*.vob > titanic.toc\n"); + exit(1); + } + + for(i = 1; i < argc; i++) + { + if(!strcmp(argv[i], "-t")) + { + timecode_search = 1; + } + else + { +/* Get just name */ + ext = strrchr(argv[i], '/'); + if(ext) + { + ext++; + strcpy(new_path, ext); + } + else + strcpy(new_path, argv[i]); + + +/* Replace suffix */ + ext = strrchr(new_path, '.'); + if(ext) + { + sprintf(ext, ".toc"); + } + else + strcat(new_path, ".toc"); + +/* fprintf(stderr, "Creating %s\n", new_path); */ + + stat(argv[i], &st); + size = (long)st.st_size; + + if(!size) + { + fprintf(stderr, "%s is 0 length. Skipping\n", new_path); + } + else + { +/* Just want the first title's streams */ + if(mpeg3_generate_toc(stdout, argv[i], timecode_search, i == argc - 1)) + { + fprintf(stderr, "Skipping %s\n", argv[i]); + } + } + } + } +} diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.c b/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.c new file mode 100644 index 0000000..dffe9d0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.c @@ -0,0 +1,33 @@ +#include "libmpeg3.h" +#include "mpeg3protos.h" + +#include + +mpeg3_vtrack_t* mpeg3_new_vtrack(mpeg3_t *file, int stream_id, mpeg3_demuxer_t *demuxer) +{ + int result = 0; + mpeg3_vtrack_t *new_vtrack; + new_vtrack = (mpeg3_vtrack_t*)calloc(1, sizeof(mpeg3_vtrack_t)); + new_vtrack->demuxer = mpeg3_new_demuxer(file, 0, 1, stream_id); + if(demuxer) mpeg3demux_copy_titles(new_vtrack->demuxer, demuxer); + new_vtrack->current_position = 0; + +/* Get information about the track here. */ + new_vtrack->video = mpeg3video_new(file, new_vtrack); + if(!new_vtrack->video) + { +/* Failed */ + mpeg3_delete_vtrack(file, new_vtrack); + new_vtrack = 0; + } + return new_vtrack; +} + +int mpeg3_delete_vtrack(mpeg3_t *file, mpeg3_vtrack_t *vtrack) +{ + if(vtrack->video) + mpeg3video_delete(vtrack->video); + if(vtrack->demuxer) + mpeg3_delete_demuxer(vtrack->demuxer); + free(vtrack); +} diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.h b/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.h new file mode 100644 index 0000000..9a3c13d --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.h @@ -0,0 +1,39 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3_VTRACK_H +#define MPEG3_VTRACK_H + +#include "mpeg3demux.h" +#include "video/mpeg3video.h" + +struct mpeg3_vtrack_rec +{ + int width; + int height; + float frame_rate; + mpeg3_demuxer_t *demuxer; + mpeg3video_t *video; + long current_position; /* Number of next frame to be played */ + long total_frames; /* Total frames in the file */ +}; + +typedef struct mpeg3_vtrack_rec mpeg3_vtrack_t; + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/ronin_narrow.toc b/core/multimedia/opieplayer/libmpeg3/ronin_narrow.toc new file mode 100644 index 0000000..07cbbf8 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/ronin_narrow.toc @@ -0,0 +1,26 @@ +TOCVERSION 2 +PATH: /cdrom/video_ts/vts_01_1.vob +ASTREAM: 0 2 +VSTREAM: 0 1 +ASTREAM: 1 2 +ASTREAM: 2 2 +SIZE: 1073709056 +PACKETSIZE: 2048 +REGION: 0 35557376 0.000000 51.643256 +REGION: 35559424 307005440 0.000000 440.561122 +REGION: 307007488 556705792 0.000000 423.698289 +REGION: 556707840 792827904 0.000000 423.877622 +REGION: 792829952 967956480 0.000000 292.754122 +REGION: 967958528 1073709056 0.000000 191.720711 +TOCVERSION 2 +PATH: /cdrom/video_ts/vts_01_2.vob +ASTREAM: 0 2 +VSTREAM: 0 1 +ASTREAM: 1 2 +ASTREAM: 2 2 +SIZE: 1073709056 +PACKETSIZE: 2048 +REGION: 0 268423168 191.722344 632.760000 +REGION: 268425216 539189248 0.000000 448.729167 +REGION: 539191296 823230464 0.000000 374.061122 +REGION: 823232512 1073709056 0.000000 421.215667 diff --git a/core/multimedia/opieplayer/libmpeg3/ronin_wide.toc b/core/multimedia/opieplayer/libmpeg3/ronin_wide.toc new file mode 100644 index 0000000..a638304 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/ronin_wide.toc @@ -0,0 +1,47 @@ +TOCVERSION 2 +PATH: /cdrom/video_ts/vts_01_1.vob +SIZE: 1073709056 +PACKETSIZE: 2048 +REGION: 0 33830912 0.000000 51.643256 +REGION: 33832960 321945600 0.000000 440.561122 +REGION: 321947648 566126592 0.000000 423.698289 +REGION: 566128640 804149248 0.000000 423.877622 +REGION: 804151296 979050496 0.000000 292.754122 +REGION: 979052544 1073709056 0.000000 170.331700 +TOCVERSION 2 +PATH: /cdrom/video_ts/vts_01_2.vob +SIZE: 1073709056 +PACKETSIZE: 2048 +REGION: 0 274845696 170.333322 632.760000 +REGION: 274847744 539138048 0.000000 448.729167 +REGION: 539140096 818880512 0.000000 374.061122 +REGION: 818882560 1073709056 0.000000 431.104722 +TOCVERSION 2 +PATH: /cdrom/video_ts/vts_01_3.vob +SIZE: 1073709056 +PACKETSIZE: 2048 +REGION: 0 3602432 431.122100 437.362056 +REGION: 3604480 316528640 0.000000 508.150422 +REGION: 316530688 562409472 0.000000 446.758722 +REGION: 562411520 728014848 0.000000 317.737689 +REGION: 728016896 943480832 0.000000 401.809556 +REGION: 943482880 1073709056 0.000000 177.871922 +TOCVERSION 2 +PATH: /cdrom/video_ts/vts_01_4.vob +SIZE: 1073709056 +PACKETSIZE: 2048 +REGION: 0 224798720 177.873544 496.357422 +REGION: 224800768 469219328 0.000000 431.833522 +REGION: 469221376 718004224 0.000000 426.048756 +REGION: 718006272 978356224 0.000000 411.668422 +REGION: 978358272 1073709056 0.000000 154.534211 +TOCVERSION 2 +PATH: /cdrom/video_ts/vts_01_5.vob +ASTREAM: 0 2 +VSTREAM: 0 1 +ASTREAM: 1 2 +ASTREAM: 2 2 +SIZE: 78041088 +PACKETSIZE: 2048 +REGION: 0 78028800 154.545878 312.853122 +REGION: 78030848 78041088 0.000000 0.006500 diff --git a/core/multimedia/opieplayer/libmpeg3/timecode.h b/core/multimedia/opieplayer/libmpeg3/timecode.h new file mode 100644 index 0000000..21e51e5 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/timecode.h @@ -0,0 +1,31 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef TIMECODE_H +#define TIMECODE_H + +typedef struct +{ + long hour; + long minute; + long second; + long frame; +} mpeg3_timecode_t; + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/video/Makefile b/core/multimedia/opieplayer/libmpeg3/video/Makefile new file mode 100644 index 0000000..46d8407 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/Makefile @@ -0,0 +1,32 @@ +include ../global_config +export CFLAGS +export CFLAGS_lessopt + +OBJS = \ + getpicture.o \ + headers.o \ + idct.o \ + macroblocks.o \ + mmxtest.o \ + motion.o \ + mpeg3video.o \ + output.o \ + reconstruct.o \ + seek.o \ + slice.o \ + vlc.o + + +all: $(OBJS) $(MMXOBJS2) + +.c.o: + $(CC) -c `./c_flags` -o $@ $< + +.s.o: + $(NASM) -f elf $*.s + +.S.o: + $(CC) -S `./c_flags` $*.S + +clean: + rm -f *.o diff --git a/core/multimedia/opieplayer/libmpeg3/video/c_flags b/core/multimedia/opieplayer/libmpeg3/video/c_flags new file mode 100755 index 0000000..d7943d0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/c_flags @@ -0,0 +1 @@ +echo $CFLAGS diff --git a/core/multimedia/opieplayer/libmpeg3/video/getpicture.c b/core/multimedia/opieplayer/libmpeg3/video/getpicture.c new file mode 100644 index 0000000..4f67484 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/getpicture.c @@ -0,0 +1,767 @@ +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "mpeg3video.h" +#include "vlc.h" + +#include +#include +#include + +int mpeg3video_get_cbp(mpeg3_slice_t *slice) +{ + int code; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + + if((code = mpeg3slice_showbits9(slice_buffer)) >= 128) + { + code >>= 4; + mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab0[code].len); + return mpeg3_CBPtab0[code].val; + } + + if(code >= 8) + { + code >>= 1; + mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab1[code].len); + return mpeg3_CBPtab1[code].val; + } + + if(code < 1) + { +/* fprintf(stderr,"mpeg3video_get_cbp: invalid coded_block_pattern code\n"); */ + slice->fault = 1; + return 0; + } + + mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab2[code].len); + return mpeg3_CBPtab2[code].val; +} + + +/* set block to zero */ +int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size) +{ + slice->sparse[comp] = 1; + +/* Compiler error */ +/* + * for(i = 0; i < size; i++) + * { + * bzero(slice->block[comp] + sizeof(short) * 64 * i, sizeof(short) * 64); + * } + */ + + if(size == 6) + { + bzero(slice->block[comp], sizeof(short) * 64 * 6); + } + else + { +printf("mpeg3video_clearblock size = %d\n", size); + memset(slice->block[comp], 0, sizeof(short) * 64 * size); + } + return 0; +} + +static inline int mpeg3video_getdclum(mpeg3_slice_buffer_t *slice_buffer) +{ + int code, size, val; +/* decode length */ + code = mpeg3slice_showbits5(slice_buffer); + + if(code < 31) + { + size = mpeg3_DClumtab0[code].val; + mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab0[code].len); + } + else + { + code = mpeg3slice_showbits9(slice_buffer) - 0x1f0; + size = mpeg3_DClumtab1[code].val; + mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab1[code].len); + } + + if(size == 0) val = 0; + else + { + val = mpeg3slice_getbits(slice_buffer, size); + if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1; + } + + return val; +} + + +int mpeg3video_getdcchrom(mpeg3_slice_buffer_t *slice_buffer) +{ + int code, size, val; + +/* decode length */ + code = mpeg3slice_showbits5(slice_buffer); + + if(code < 31) + { + size = mpeg3_DCchromtab0[code].val; + mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab0[code].len); + } + else + { + code = mpeg3slice_showbits(slice_buffer, 10) - 0x3e0; + size = mpeg3_DCchromtab1[code].val; + mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab1[code].len); + } + + if(size == 0) val = 0; + else + { + val = mpeg3slice_getbits(slice_buffer, size); + if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1; + } + + return val; +} + + +/* decode one intra coded MPEG-1 block */ + +int mpeg3video_getintrablock(mpeg3_slice_t *slice, + mpeg3video_t *video, + int comp, + int dc_dct_pred[]) +{ + int val, i, j, sign; + unsigned int code; + mpeg3_DCTtab_t *tab = 0; + short *bp = slice->block[comp]; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + +/* decode DC coefficients */ + if(comp < 4) + bp[0] = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)) << 3; + else + if(comp == 4) + bp[0] = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)) << 3; + else + bp[0] = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)) << 3; + +#ifdef HAVE_MMX + if(video->have_mmx) + bp[0] <<= 4; +#endif + + if(slice->fault) return 1; + +/* decode AC coefficients */ + for(i = 1; ; i++) + { + code = mpeg3slice_showbits16(slice_buffer); + if(code >= 16384) + tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; + else + if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4]; + else + if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8]; + else + if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; + else + if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; + else + if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16]; + else + if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16]; + else + if(code >= 16) tab = &mpeg3_DCTtab6[code - 16]; + else + { +/* fprintf(stderr, "mpeg3video_getintrablock: invalid Huffman code\n"); */ + slice->fault = 1; + return 1; + } + + mpeg3slice_flushbits(slice_buffer, tab->len); + + if(tab->run == 64) break; /* end_of_block */ + + if(tab->run == 65) + { +/* escape */ + i += mpeg3slice_getbits(slice_buffer, 6); + + if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0) + val = mpeg3slice_getbits(slice_buffer, 8); + else + if(val == 128) + val = mpeg3slice_getbits(slice_buffer, 8) - 256; + else + if(val > 128) + val -= 256; + + if((sign = (val < 0)) != 0) val= -val; + } + else + { + i += tab->run; + val = tab->level; + sign = mpeg3slice_getbit(slice_buffer); + } + + if(i < 64) + j = video->mpeg3_zigzag_scan_table[i]; + else + { + slice->fault = 1; + return 1; + } + + +#ifdef HAVE_MMX + if(video->have_mmx) + { + val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) << 1; + val = (val - 16) | 16; + } + else +#endif + { + val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) >> 3; + val = (val - 1) | 1; + } + + bp[j] = sign ? -val : val; + } + + if(j != 0) + { +/* not a sparse matrix ! */ + slice->sparse[comp] = 0; + } + return 0; +} + + +/* decode one non-intra coded MPEG-1 block */ + +int mpeg3video_getinterblock(mpeg3_slice_t *slice, + mpeg3video_t *video, + int comp) +{ + int val, i, j, sign; + unsigned int code; + mpeg3_DCTtab_t *tab; + short *bp = slice->block[comp]; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + +/* decode AC coefficients */ + for(i = 0; ; i++) + { + code = mpeg3slice_showbits16(slice_buffer); + if(code >= 16384) + { + if(i == 0) + tab = &mpeg3_DCTtabfirst[(code >> 12) - 4]; + else + tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; + } + else + if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4]; + else + if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8]; + else + if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; + else + if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; + else + if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16]; + else + if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16]; + else + if(code >= 16) tab = &mpeg3_DCTtab6[code - 16]; + else + { +// invalid Huffman code + slice->fault = 1; + return 1; + } + + mpeg3slice_flushbits(slice_buffer, tab->len); + +/* end of block */ + if(tab->run == 64) + break; + + if(tab->run == 65) + { +/* escape */ + i += mpeg3slice_getbits(slice_buffer, 6); + if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0) + val = mpeg3slice_getbits(slice_buffer, 8); + else + if(val == 128) + val = mpeg3slice_getbits(slice_buffer, 8) - 256; + else + if(val > 128) + val -= 256; + + if((sign = (val < 0)) != 0) val = -val; + } + else + { + i += tab->run; + val = tab->level; + sign = mpeg3slice_getbit(slice_buffer); + } + + j = video->mpeg3_zigzag_scan_table[i]; + +#ifdef HAVE_MMX + if(video->have_mmx) + { + val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]); + val = (val - 16) | 16; + } + else +#endif + { + val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]) >> 4; + val = (val - 1) | 1; + } + + bp[j] = sign ? -val : val; + } + + if(j != 0) + { +/* not a sparse matrix ! */ + slice->sparse[comp] = 0; + } + return 0; +} + + +/* decode one intra coded MPEG-2 block */ +int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice, + mpeg3video_t *video, + int comp, + int dc_dct_pred[]) +{ + int val, i, j, sign, nc; + unsigned int code; + mpeg3_DCTtab_t *tab; + short *bp; + int *qmat; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + +/* with data partitioning, data always goes to base layer */ + bp = slice->block[comp]; + + qmat = (comp < 4 || video->chroma_format == CHROMA420) + ? video->intra_quantizer_matrix + : video->chroma_intra_quantizer_matrix; + +/* decode DC coefficients */ + if(comp < 4) + val = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)); + else + if((comp & 1) == 0) + val = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)); + else + val = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)); + + if(slice->fault) return 1; +#ifdef HAVE_MMX + if(video->have_mmx) + bp[0] = val << (7 - video->dc_prec); + else +#endif + bp[0] = val << (3 - video->dc_prec); + + nc = 0; + +/* decode AC coefficients */ + for(i = 1; ; i++) + { + code = mpeg3slice_showbits16(slice_buffer); + + if(code >= 16384 && !video->intravlc) + tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; + else + if(code >= 1024) + { + if(video->intravlc) + tab = &mpeg3_DCTtab0a[(code >> 8) - 4]; + else + tab = &mpeg3_DCTtab0[(code >> 8) - 4]; + } + else + if(code >= 512) + { + if(video->intravlc) + tab = &mpeg3_DCTtab1a[(code >> 6) - 8]; + else + tab = &mpeg3_DCTtab1[(code >> 6) - 8]; + } + else + if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; + else + if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; + else + if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16]; + else + if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16]; + else + if(code >= 16) tab = &mpeg3_DCTtab6[code - 16]; + else + { +/* fprintf(stderr,"mpeg3video_getmpg2intrablock: invalid Huffman code\n"); */ + slice->fault = 1; + return 1; + } + + mpeg3slice_flushbits(slice_buffer, tab->len); + +/* end_of_block */ + if(tab->run == 64) + break; + + if(tab->run == 65) + { +/* escape */ + i += mpeg3slice_getbits(slice_buffer, 6); + + val = mpeg3slice_getbits(slice_buffer, 12); + if((val & 2047) == 0) + { +// invalid signed_level (escape) + slice->fault = 1; + return 1; + } + if((sign = (val >= 2048)) != 0) val = 4096 - val; + } + else + { + i += tab->run; + val = tab->level; + sign = mpeg3slice_getbit(slice_buffer); + } + + j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i]; + +#ifdef HAVE_MMX + if(video->have_mmx) + val = (val * slice->quant_scale * qmat[j]); + else +#endif + val = (val * slice->quant_scale * qmat[j]) >> 4; + + bp[j] = sign ? -val : val; + nc++; + } + + if(j != 0) + { +/* not a sparse matrix ! */ + slice->sparse[comp] = 0; + } + return 1; +} + + +/* decode one non-intra coded MPEG-2 block */ + +int mpeg3video_getmpg2interblock(mpeg3_slice_t *slice, + mpeg3video_t *video, + int comp) +{ + int val, i, j, sign, nc; + unsigned int code; + mpeg3_DCTtab_t *tab; + short *bp; + int *qmat; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + +/* with data partitioning, data always goes to base layer */ + bp = slice->block[comp]; + + qmat = (comp < 4 || video->chroma_format == CHROMA420) + ? video->non_intra_quantizer_matrix + : video->chroma_non_intra_quantizer_matrix; + + nc = 0; + +/* decode AC coefficients */ + for(i = 0; ; i++) + { + code = mpeg3slice_showbits16(slice_buffer); + if(code >= 16384) + { + if(i == 0) tab = &mpeg3_DCTtabfirst[(code >> 12) - 4]; + else tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; + } + else + if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4]; + else + if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8]; + else + if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; + else + if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; + else + if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16]; + else + if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16]; + else + if(code >= 16) tab = &mpeg3_DCTtab6[code - 16]; + else + { +// invalid Huffman code + slice->fault = 1; + return 1; + } + + mpeg3slice_flushbits(slice_buffer, tab->len); + +/* end_of_block */ + if(tab->run == 64) + break; + + if(tab->run == 65) + { +/* escape */ + i += mpeg3slice_getbits(slice_buffer, 6); + val = mpeg3slice_getbits(slice_buffer, 12); + if((val & 2047) == 0) + { +/* fprintf(stderr, "mpeg3video_getmpg2interblock: invalid signed_level (escape)\n"); */ + slice->fault = 1; + return 1; + } + if((sign = (val >= 2048)) != 0) val = 4096 - val; + } + else + { + i += tab->run; + val = tab->level; + sign = mpeg3slice_getbit(slice_buffer); + } + + j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i]; + +#ifdef HAVE_MMX + if(video->have_mmx) + val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 1; + else +#endif + val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 5; + + bp[j] = sign ? (-val) : val ; + nc++; + } + + if(j != 0) + { + slice->sparse[comp] = 0; + } + return 0; +} + + +/* decode all macroblocks of the current picture */ +int mpeg3video_get_macroblocks(mpeg3video_t *video, int framenum) +{ + unsigned int code; + mpeg3_slice_buffer_t *slice_buffer; /* Buffer being loaded */ + int i; + int current_buffer; + mpeg3_bits_t *vstream = video->vstream; + +/* Load every slice into a buffer array */ + video->total_slice_buffers = 0; + current_buffer = 0; + while(!mpeg3bits_eof(vstream) && + mpeg3bits_showbits32_noptr(vstream) >= MPEG3_SLICE_MIN_START && + mpeg3bits_showbits32_noptr(vstream) <= MPEG3_SLICE_MAX_START) + { +/* Initialize the buffer */ + if(current_buffer >= video->slice_buffers_initialized) + mpeg3_new_slice_buffer(&(video->slice_buffers[video->slice_buffers_initialized++])); + slice_buffer = &(video->slice_buffers[current_buffer]); + slice_buffer->buffer_size = 0; + slice_buffer->current_position = 0; + slice_buffer->bits_size = 0; + slice_buffer->done = 0; + +/* Read the slice into the buffer including the slice start code */ + do + { +/* Expand buffer */ + if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size) + mpeg3_expand_slice_buffer(slice_buffer); + +/* Load 1 char into buffer */ + slice_buffer->data[slice_buffer->buffer_size++] = mpeg3bits_getbyte_noptr(vstream); + }while(!mpeg3bits_eof(vstream) && + mpeg3bits_showbits24_noptr(vstream) != MPEG3_PACKET_START_CODE_PREFIX); + +/* Pad the buffer to get the last macroblock */ + if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size + 4) + mpeg3_expand_slice_buffer(slice_buffer); + + slice_buffer->data[slice_buffer->buffer_size++] = 0; + slice_buffer->data[slice_buffer->buffer_size++] = 0; + slice_buffer->data[slice_buffer->buffer_size++] = 1; + slice_buffer->data[slice_buffer->buffer_size++] = 0; + slice_buffer->bits_size = 0; + + pthread_mutex_lock(&(slice_buffer->completion_lock)); fflush(stdout); + current_buffer++; + video->total_slice_buffers++; + } + +/* Run the slice decoders */ + if(video->total_slice_buffers > 0) + { + for(i = 0; i < video->total_slice_decoders; i++) + { + if(i == 0 && video->total_slice_decoders > 1) + { + video->slice_decoders[i].current_buffer = 0; + video->slice_decoders[i].buffer_step = 1; + video->slice_decoders[i].last_buffer = (video->total_slice_buffers - 1); + } + else + if(i == 1) + { + video->slice_decoders[i].current_buffer = video->total_slice_buffers - 1; + video->slice_decoders[i].buffer_step = -1; + video->slice_decoders[i].last_buffer = 0; + } + else + { + video->slice_decoders[i].current_buffer = i; + video->slice_decoders[i].buffer_step = 1; + video->slice_decoders[i].last_buffer = video->total_slice_buffers - 1; + } + pthread_mutex_unlock(&(video->slice_decoders[i].input_lock)); + } + } + +/* Wait for the slice decoders to finish */ + if(video->total_slice_buffers > 0) + { + for(i = 0; i < video->total_slice_buffers; i++) + { + pthread_mutex_lock(&(video->slice_buffers[i].completion_lock)); + pthread_mutex_unlock(&(video->slice_buffers[i].completion_lock)); + } + } + return 0; +} + +int mpeg3video_allocate_decoders(mpeg3video_t *video, int decoder_count) +{ + int i; + mpeg3_t *file = video->file; +/* Get the slice decoders */ + if(video->total_slice_decoders != file->cpus) + { + for(i = 0; i < video->total_slice_decoders; i++) + { + mpeg3_delete_slice_decoder(&video->slice_decoders[i]); + } + + for(i = 0; i < file->cpus && i < MPEG3_MAX_CPUS; i++) + { + mpeg3_new_slice_decoder(video, &(video->slice_decoders[i])); + video->slice_decoders[i].thread_number = i; + } + + video->total_slice_decoders = file->cpus; + } + return 0; +} + +/* decode one frame or field picture */ + +int mpeg3video_getpicture(mpeg3video_t *video, int framenum) +{ + int i, result = 0; + mpeg3_t *file = video->file; + + if(video->pict_struct == FRAME_PICTURE && video->secondfield) + { +/* recover from illegal number of field pictures */ + video->secondfield = 0; + } + + if(!video->mpeg2) + { + video->current_repeat = video->repeat_count = 0; + } + + mpeg3video_allocate_decoders(video, file->cpus); + + for(i = 0; i < 3; i++) + { + if(video->pict_type == B_TYPE) + { + video->newframe[i] = video->auxframe[i]; + } + else + { + if(!video->secondfield && !video->current_repeat) + { +/* Swap refframes for I frames */ + unsigned char* tmp = video->oldrefframe[i]; + video->oldrefframe[i] = video->refframe[i]; + video->refframe[i] = tmp; + } + + video->newframe[i] = video->refframe[i]; + } + + if(video->pict_struct == BOTTOM_FIELD) + { +/* Only used if fields are in different pictures */ + video->newframe[i] += (i == 0) ? video->coded_picture_width : video->chrom_width; + } + } + +/* The problem is when a B frame lands on the first repeat and is skipped, */ +/* the second repeat goes for the same bitmap as the skipped repeat, */ +/* so it picks up a frame from 3 frames back. */ +/* The first repeat must consititutively read a B frame if its B frame is going to be */ +/* used in a later repeat. */ + if(!video->current_repeat) + if(!(video->skip_bframes && video->pict_type == B_TYPE) || + (video->repeat_count >= 100 + 100 * video->skip_bframes)) + result = mpeg3video_get_macroblocks(video, framenum); + +/* Set the frame to display */ + video->output_src = 0; + if(framenum > -1 && !result) + { + if(video->pict_struct == FRAME_PICTURE || video->secondfield) + { + if(video->pict_type == B_TYPE) + { + video->output_src = video->auxframe; + } + else + { + video->output_src = video->oldrefframe; + } + } + else + { + mpeg3video_display_second_field(video); + } + } + + if(video->mpeg2) + { + video->current_repeat += 100; + } + + if(video->pict_struct != FRAME_PICTURE) video->secondfield = !video->secondfield; + return result; +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/headers.c b/core/multimedia/opieplayer/libmpeg3/video/headers.c new file mode 100644 index 0000000..5274530 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/headers.c @@ -0,0 +1,492 @@ +#include "../mpeg3demux.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "mpeg3video.h" + +#include +#include + +int mpeg3video_getseqhdr(mpeg3video_t *video) +{ + int i; + mpeg3_t *file = video->file; + + int aspect_ratio, picture_rate, vbv_buffer_size; + int constrained_parameters_flag; + int load_intra_quantizer_matrix, load_non_intra_quantizer_matrix; + + video->horizontal_size = mpeg3bits_getbits(video->vstream, 12); + video->vertical_size = mpeg3bits_getbits(video->vstream, 12); + aspect_ratio = mpeg3bits_getbits(video->vstream, 4); + video->framerate_code = mpeg3bits_getbits(video->vstream, 4); + video->bitrate = mpeg3bits_getbits(video->vstream, 18); + mpeg3bits_getbit_noptr(video->vstream); /* marker bit (=1) */ + vbv_buffer_size = mpeg3bits_getbits(video->vstream, 10); + constrained_parameters_flag = mpeg3bits_getbit_noptr(video->vstream); + video->frame_rate = mpeg3_frame_rate_table[video->framerate_code]; + + load_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream); + if(load_intra_quantizer_matrix) + { + for(i = 0; i < 64; i++) + video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); + } + else + { + for(i = 0; i < 64; i++) + video->intra_quantizer_matrix[i] = mpeg3_default_intra_quantizer_matrix[i]; + } + + load_non_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream); + if(load_non_intra_quantizer_matrix) + { + for(i = 0; i < 64; i++) + video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); + } + else + { + for(i = 0; i < 64; i++) + video->non_intra_quantizer_matrix[i] = 16; + } + +/* copy luminance to chrominance matrices */ + for(i = 0; i < 64; i++) + { + video->chroma_intra_quantizer_matrix[i] = video->intra_quantizer_matrix[i]; + video->chroma_non_intra_quantizer_matrix[i] = video->non_intra_quantizer_matrix[i]; + } + + return 0; +} + + +/* decode sequence extension */ + +int mpeg3video_sequence_extension(mpeg3video_t *video) +{ + int prof_lev; + int horizontal_size_extension, vertical_size_extension; + int bit_rate_extension, vbv_buffer_size_extension, low_delay; + int frame_rate_extension_n, frame_rate_extension_d; + int pos = 0; + + video->mpeg2 = 1; + video->scalable_mode = SC_NONE; /* unless overwritten by seq. scal. ext. */ + prof_lev = mpeg3bits_getbyte_noptr(video->vstream); + video->prog_seq = mpeg3bits_getbit_noptr(video->vstream); + video->chroma_format = mpeg3bits_getbits(video->vstream, 2); + horizontal_size_extension = mpeg3bits_getbits(video->vstream, 2); + vertical_size_extension = mpeg3bits_getbits(video->vstream, 2); + bit_rate_extension = mpeg3bits_getbits(video->vstream, 12); + mpeg3bits_getbit_noptr(video->vstream); + vbv_buffer_size_extension = mpeg3bits_getbyte_noptr(video->vstream); + low_delay = mpeg3bits_getbit_noptr(video->vstream); + frame_rate_extension_n = mpeg3bits_getbits(video->vstream, 2); + frame_rate_extension_d = mpeg3bits_getbits(video->vstream, 5); + video->horizontal_size = (horizontal_size_extension << 12) | (video->horizontal_size & 0x0fff); + video->vertical_size = (vertical_size_extension << 12) | (video->vertical_size & 0x0fff); +} + + +/* decode sequence display extension */ + +int mpeg3video_sequence_display_extension(mpeg3video_t *video) +{ + int colour_primaries = 0, transfer_characteristics = 0; + int display_horizontal_size, display_vertical_size; + int pos = 0; + int video_format = mpeg3bits_getbits(video->vstream, 3); + int colour_description = mpeg3bits_getbit_noptr(video->vstream); + + if(colour_description) + { + colour_primaries = mpeg3bits_getbyte_noptr(video->vstream); + transfer_characteristics = mpeg3bits_getbyte_noptr(video->vstream); + video->matrix_coefficients = mpeg3bits_getbyte_noptr(video->vstream); + } + + display_horizontal_size = mpeg3bits_getbits(video->vstream, 14); + mpeg3bits_getbit_noptr(video->vstream); + display_vertical_size = mpeg3bits_getbits(video->vstream, 14); +} + + +/* decode quant matrix entension */ + +int mpeg3video_quant_matrix_extension(mpeg3video_t *video) +{ + int i; + int load_intra_quantiser_matrix, load_non_intra_quantiser_matrix; + int load_chroma_intra_quantiser_matrix; + int load_chroma_non_intra_quantiser_matrix; + int pos = 0; + + if((load_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) + { + for(i = 0; i < 64; i++) + { + video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] + = video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] + = mpeg3bits_getbyte_noptr(video->vstream); + } + } + + if((load_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) + { + for (i = 0; i < 64; i++) + { + video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] + = video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] + = mpeg3bits_getbyte_noptr(video->vstream); + } + } + + if((load_chroma_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) + { + for(i = 0; i < 64; i++) + video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); + } + + if((load_chroma_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) + { + for(i = 0; i < 64; i++) + video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); + } +} + + +/* decode sequence scalable extension */ + +int mpeg3video_sequence_scalable_extension(mpeg3video_t *video) +{ + int layer_id; + + video->scalable_mode = mpeg3bits_getbits(video->vstream, 2) + 1; /* add 1 to make SC_DP != SC_NONE */ + layer_id = mpeg3bits_getbits(video->vstream, 4); + + if(video->scalable_mode == SC_SPAT) + { + video->llw = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_horizontal_size */ + mpeg3bits_getbit_noptr(video->vstream); + video->llh = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_vertical_size */ + video->hm = mpeg3bits_getbits(video->vstream, 5); + video->hn = mpeg3bits_getbits(video->vstream, 5); + video->vm = mpeg3bits_getbits(video->vstream, 5); + video->vn = mpeg3bits_getbits(video->vstream, 5); + } + + if(video->scalable_mode == SC_TEMP) + fprintf(stderr, "mpeg3video_sequence_scalable_extension: temporal scalability not implemented\n"); +} + + +/* decode picture display extension */ + +int mpeg3video_picture_display_extension(mpeg3video_t *video) +{ + int n, i; + short frame_centre_horizontal_offset[3]; + short frame_centre_vertical_offset[3]; + + if(video->prog_seq || video->pict_struct != FRAME_PICTURE) + n = 1; + else + n = video->repeatfirst ? 3 : 2; + + for(i = 0; i < n; i++) + { + frame_centre_horizontal_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16); + mpeg3bits_getbit_noptr(video->vstream); + frame_centre_vertical_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16); + mpeg3bits_getbit_noptr(video->vstream); + } +} + + +/* decode picture coding extension */ + +int mpeg3video_picture_coding_extension(mpeg3video_t *video) +{ + int chroma_420_type, composite_display_flag; + int v_axis = 0, field_sequence = 0, sub_carrier = 0, burst_amplitude = 0, sub_carrier_phase = 0; + + video->h_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; + video->v_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; + video->h_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; + video->v_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; + video->dc_prec = mpeg3bits_getbits(video->vstream, 2); + video->pict_struct = mpeg3bits_getbits(video->vstream, 2); + video->topfirst = mpeg3bits_getbit_noptr(video->vstream); + video->frame_pred_dct = mpeg3bits_getbit_noptr(video->vstream); + video->conceal_mv = mpeg3bits_getbit_noptr(video->vstream); + video->qscale_type = mpeg3bits_getbit_noptr(video->vstream); + video->intravlc = mpeg3bits_getbit_noptr(video->vstream); + video->altscan = mpeg3bits_getbit_noptr(video->vstream); + video->repeatfirst = mpeg3bits_getbit_noptr(video->vstream); + chroma_420_type = mpeg3bits_getbit_noptr(video->vstream); + video->prog_frame = mpeg3bits_getbit_noptr(video->vstream); + + if(video->repeat_count > 100) + video->repeat_count = 0; + video->repeat_count += 100; + + video->current_repeat = 0; + + if(video->prog_seq) + { + if(video->repeatfirst) + { + if(video->topfirst) + video->repeat_count += 200; + else + video->repeat_count += 100; + } + } + else + if(video->prog_frame) + { + if(video->repeatfirst) + { + video->repeat_count += 50; + } + } + +/*printf("mpeg3video_picture_coding_extension %d\n", video->repeat_count); */ + composite_display_flag = mpeg3bits_getbit_noptr(video->vstream); + + if(composite_display_flag) + { + v_axis = mpeg3bits_getbit_noptr(video->vstream); + field_sequence = mpeg3bits_getbits(video->vstream, 3); + sub_carrier = mpeg3bits_getbit_noptr(video->vstream); + burst_amplitude = mpeg3bits_getbits(video->vstream, 7); + sub_carrier_phase = mpeg3bits_getbyte_noptr(video->vstream); + } +} + + +/* decode picture spatial scalable extension */ + +int mpeg3video_picture_spatial_scalable_extension(mpeg3video_t *video) +{ + video->pict_scal = 1; /* use spatial scalability in this picture */ + + video->lltempref = mpeg3bits_getbits(video->vstream, 10); + mpeg3bits_getbit_noptr(video->vstream); + video->llx0 = mpeg3bits_getbits(video->vstream, 15); + if(video->llx0 >= 16384) video->llx0 -= 32768; + mpeg3bits_getbit_noptr(video->vstream); + video->lly0 = mpeg3bits_getbits(video->vstream, 15); + if(video->lly0 >= 16384) video->lly0 -= 32768; + video->stwc_table_index = mpeg3bits_getbits(video->vstream, 2); + video->llprog_frame = mpeg3bits_getbit_noptr(video->vstream); + video->llfieldsel = mpeg3bits_getbit_noptr(video->vstream); +} + + +/* decode picture temporal scalable extension + * + * not implemented + * + */ + +int mpeg3video_picture_temporal_scalable_extension(mpeg3video_t *video) +{ + fprintf(stderr, "mpeg3video_picture_temporal_scalable_extension: temporal scalability not supported\n"); +} + + +/* decode extension and user data */ + +int mpeg3video_ext_user_data(mpeg3video_t *video) +{ + int code = mpeg3bits_next_startcode(video->vstream); + + + while(code == MPEG3_EXT_START_CODE || code == MPEG3_USER_START_CODE && + !mpeg3bits_eof(video->vstream)) + { + mpeg3bits_refill(video->vstream); + + if(code == MPEG3_EXT_START_CODE) + { + int ext_id = mpeg3bits_getbits(video->vstream, 4); + switch(ext_id) + { + case SEQ_ID: + mpeg3video_sequence_extension(video); + break; + case DISP_ID: + mpeg3video_sequence_display_extension(video); + break; + case QUANT_ID: + mpeg3video_quant_matrix_extension(video); + break; + case SEQSCAL_ID: + mpeg3video_sequence_scalable_extension(video); + break; + case PANSCAN_ID: + mpeg3video_picture_display_extension(video); + break; + case CODING_ID: + mpeg3video_picture_coding_extension(video); + break; + case SPATSCAL_ID: + mpeg3video_picture_spatial_scalable_extension(video); + break; + case TEMPSCAL_ID: + mpeg3video_picture_temporal_scalable_extension(video); + break; + default: + fprintf(stderr,"mpeg3video_ext_user_data: reserved extension start code ID %d\n", ext_id); + break; + } + } + code = mpeg3bits_next_startcode(video->vstream); + } +} + + +/* decode group of pictures header */ + +int mpeg3video_getgophdr(mpeg3video_t *video) +{ + int drop_flag, closed_gop, broken_link; + + drop_flag = mpeg3bits_getbit_noptr(video->vstream); + video->gop_timecode.hour = mpeg3bits_getbits(video->vstream, 5); + video->gop_timecode.minute = mpeg3bits_getbits(video->vstream, 6); + mpeg3bits_getbit_noptr(video->vstream); + video->gop_timecode.second = mpeg3bits_getbits(video->vstream, 6); + video->gop_timecode.frame = mpeg3bits_getbits(video->vstream, 6); + closed_gop = mpeg3bits_getbit_noptr(video->vstream); + broken_link = mpeg3bits_getbit_noptr(video->vstream); + +/* + * printf("%d:%d:%d:%d %d %d %d\n", video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, + * drop_flag, closed_gop, broken_link); + */ + return mpeg3bits_error(video->vstream); +} + +/* decode picture header */ + +int mpeg3video_getpicturehdr(mpeg3video_t *video) +{ + int temp_ref, vbv_delay; + + video->pict_scal = 0; /* unless overwritten by pict. spat. scal. ext. */ + + temp_ref = mpeg3bits_getbits(video->vstream, 10); + video->pict_type = mpeg3bits_getbits(video->vstream, 3); + vbv_delay = mpeg3bits_getbits(video->vstream, 16); + + if(video->pict_type == P_TYPE || video->pict_type == B_TYPE) + { + video->full_forw = mpeg3bits_getbit_noptr(video->vstream); + video->forw_r_size = mpeg3bits_getbits(video->vstream, 3) - 1; + } + + if(video->pict_type == B_TYPE) + { + video->full_back = mpeg3bits_getbit_noptr(video->vstream); + video->back_r_size = mpeg3bits_getbits(video->vstream, 3) - 1; + } + +/* get extra bit picture */ + while(mpeg3bits_getbit_noptr(video->vstream) && + !mpeg3bits_eof(video->vstream)) mpeg3bits_getbyte_noptr(video->vstream); + return 0; +} + + +int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat) +{ + unsigned int code; + +/* a sequence header should be found before returning from `getheader' the */ +/* first time (this is to set horizontal/vertical size properly) */ + +/* Repeat the frame until it's less than 1 count from repeat_count */ + if(video->repeat_count - video->current_repeat >= 100 && !dont_repeat) + { + return 0; + } + + if(dont_repeat) + { + video->repeat_count = 0; + video->current_repeat = 0; + } + else + video->repeat_count -= video->current_repeat; + + while(1) + { +/* look for startcode */ + code = mpeg3bits_next_startcode(video->vstream); + if(mpeg3bits_eof(video->vstream)) return 1; + if(code != MPEG3_SEQUENCE_END_CODE) mpeg3bits_refill(video->vstream); + + switch(code) + { + case MPEG3_SEQUENCE_START_CODE: + video->found_seqhdr = 1; + mpeg3video_getseqhdr(video); + mpeg3video_ext_user_data(video); + break; + + case MPEG3_GOP_START_CODE: + mpeg3video_getgophdr(video); + mpeg3video_ext_user_data(video); + break; + + case MPEG3_PICTURE_START_CODE: + mpeg3video_getpicturehdr(video); + mpeg3video_ext_user_data(video); + if(video->found_seqhdr) return 0; /* Exit here */ + break; + + case MPEG3_SEQUENCE_END_CODE: +// Continue until the end + mpeg3bits_refill(video->vstream); + break; + + default: + break; + } + } + return 1; /* Shouldn't be reached. */ +} + +int mpeg3video_ext_bit_info(mpeg3_slice_buffer_t *slice_buffer) +{ + while(mpeg3slice_getbit(slice_buffer)) mpeg3slice_getbyte(slice_buffer); + return 0; +} + +/* decode slice header */ +int mpeg3video_getslicehdr(mpeg3_slice_t *slice, mpeg3video_t *video) +{ + int slice_vertical_position_extension, intra_slice; + int qs; + + slice_vertical_position_extension = (video->mpeg2 && video->vertical_size > 2800) ? + mpeg3slice_getbits(slice->slice_buffer, 3) : 0; + + if(video->scalable_mode == SC_DP) slice->pri_brk = mpeg3slice_getbits(slice->slice_buffer, 7); + + qs = mpeg3slice_getbits(slice->slice_buffer, 5); + slice->quant_scale = video->mpeg2 ? (video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1)) : qs; + + if(mpeg3slice_getbit(slice->slice_buffer)) + { + intra_slice = mpeg3slice_getbit(slice->slice_buffer); + mpeg3slice_getbits(slice->slice_buffer, 7); + mpeg3video_ext_bit_info(slice->slice_buffer); + } + else + intra_slice = 0; + + return slice_vertical_position_extension; +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/idct.c b/core/multimedia/opieplayer/libmpeg3/video/idct.c new file mode 100644 index 0000000..c79f90a --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/idct.c @@ -0,0 +1,160 @@ +#include "idct.h" +#include + +/**********************************************************/ +/* inverse two dimensional DCT, Chen-Wang algorithm */ +/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */ +/* 32-bit integer arithmetic (8 bit coefficients) */ +/* 11 mults, 29 adds per DCT */ +/* sE, 18.8.91 */ +/**********************************************************/ +/* coefficients extended to 12 bit for IEEE1180-1990 */ +/* compliance sE, 2.1.94 */ +/**********************************************************/ + +/* this code assumes >> to be a two's-complement arithmetic */ +/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ + +#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */ +#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */ +#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */ +#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */ +#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */ +#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */ + +/* row (horizontal) IDCT + * + * 7 pi 1 + * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l ) + * l=0 8 2 + * + * where: c[0] = 128 + * c[1..7] = 128*sqrt(2) + */ + +int mpeg3video_idctrow(short *blk) +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + /* shortcut */ + if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) | + (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3]))) + { + blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3; + return 0; + } + + x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */ + + /* first stage */ + x8 = W7*(x4+x5); + x4 = x8 + (W1-W7)*x4; + x5 = x8 - (W1+W7)*x5; + x8 = W3*(x6+x7); + x6 = x8 - (W3-W5)*x6; + x7 = x8 - (W3+W5)*x7; + + /* second stage */ + x8 = x0 + x1; + x0 -= x1; + x1 = W6*(x3+x2); + x2 = x1 - (W2+W6)*x2; + x3 = x1 + (W2-W6)*x3; + x1 = x4 + x6; + x4 -= x6; + x6 = x5 + x7; + x5 -= x7; + + /* third stage */ + x7 = x8 + x3; + x8 -= x3; + x3 = x0 + x2; + x0 -= x2; + x2 = (181*(x4+x5)+128)>>8; + x4 = (181*(x4-x5)+128)>>8; + + /* fourth stage */ + blk[0] = (x7+x1)>>8; + blk[1] = (x3+x2)>>8; + blk[2] = (x0+x4)>>8; + blk[3] = (x8+x6)>>8; + blk[4] = (x8-x6)>>8; + blk[5] = (x0-x4)>>8; + blk[6] = (x3-x2)>>8; + blk[7] = (x7-x1)>>8; + + return 1; +} + +/* column (vertical) IDCT + * + * 7 pi 1 + * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l ) + * l=0 8 2 + * + * where: c[0] = 1/1024 + * c[1..7] = (1/1024)*sqrt(2) + */ + +int mpeg3video_idctcol(short *blk) +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + /* shortcut */ + if (!((x1 = (blk[8 * 4]<<8)) | (x2 = blk[8 * 6]) | (x3 = blk[8 * 2]) | + (x4 = blk[8*1]) | (x5 = blk[8 * 7]) | (x6 = blk[8 * 5]) | (x7 = blk[8 * 3]))){ + blk[8*0]=blk[8*1]=blk[8 * 2]=blk[8 * 3]=blk[8 * 4]=blk[8 * 5]=blk[8 * 6]=blk[8 * 7]= + (blk[8*0]+32)>>6; + return 0; + } + + x0 = (blk[8*0]<<8) + 8192; + + /* first stage */ + x8 = W7*(x4+x5) + 4; + x4 = (x8+(W1-W7)*x4)>>3; + x5 = (x8-(W1+W7)*x5)>>3; + x8 = W3*(x6+x7) + 4; + x6 = (x8-(W3-W5)*x6)>>3; + x7 = (x8-(W3+W5)*x7)>>3; + + /* second stage */ + x8 = x0 + x1; + x0 -= x1; + x1 = W6*(x3+x2) + 4; + x2 = (x1-(W2+W6)*x2)>>3; + x3 = (x1+(W2-W6)*x3)>>3; + x1 = x4 + x6; + x4 -= x6; + x6 = x5 + x7; + x5 -= x7; + + /* third stage */ + x7 = x8 + x3; + x8 -= x3; + x3 = x0 + x2; + x0 -= x2; + x2 = (181 * (x4 + x5) + 128) >> 8; + x4 = (181 * (x4 - x5) + 128) >> 8; + + /* fourth stage */ + blk[8 * 0] = (x7 + x1) >> 14; + blk[8 * 1] = (x3 + x2) >> 14; + blk[8 * 2] = (x0 + x4) >> 14; + blk[8 * 3] = (x8 + x6) >> 14; + blk[8 * 4] = (x8 - x6) >> 14; + blk[8 * 5] = (x0 - x4) >> 14; + blk[8 * 6] = (x3 - x2) >> 14; + blk[8 * 7] = (x7 - x1) >> 14; + + return 1; +} + + +/* two dimensional inverse discrete cosine transform */ +void mpeg3video_idct_conversion(short* block) +{ + int i; + for(i = 0; i < 8; i++) mpeg3video_idctrow(block + 8 * i); + for(i = 0; i < 8; i++) mpeg3video_idctcol(block + i); +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/idct.h b/core/multimedia/opieplayer/libmpeg3/video/idct.h new file mode 100644 index 0000000..f0aa1d8 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/idct.h @@ -0,0 +1,24 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef IDCT_H +#define IDCT_H + + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/video/layerdata.h b/core/multimedia/opieplayer/libmpeg3/video/layerdata.h new file mode 100644 index 0000000..3ef0f90 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/layerdata.h @@ -0,0 +1,35 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LAYERDATA_H +#define LAYERDATA_H + +typedef struct +{ +/* sequence header */ + int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64]; + int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64]; + int mpeg2; + int qscale_type, altscan; /* picture coding extension */ + int pict_scal; /* picture spatial scalable extension */ + int scalable_mode; /* sequence scalable extension */ +} mpeg3_layerdata_t; + + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c new file mode 100644 index 0000000..11e17c1 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c @@ -0,0 +1,338 @@ +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "mpeg3video.h" +#include "slice.h" +#include "vlc.h" + +#include + +int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice) +{ + int code, val = 0; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + + while((code = mpeg3slice_showbits(slice_buffer, 11)) < 24) + { +/* Is not macroblock_stuffing */ + if(code != 15) + { +/* Is macroblock_escape */ + if(code == 8) + { + val += 33; + } + else + { +/* fprintf(stderr, "mpeg3video_get_macroblock_address: invalid macroblock_address_increment code\n"); */ + slice->fault = 1; + return 1; + } + } + + mpeg3slice_flushbits(slice_buffer, 11); + } + + if(code >= 1024) + { + mpeg3slice_flushbit(slice_buffer); + return val + 1; + } + + if(code >= 128) + { + code >>= 6; + mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab1[code].len); + return val + mpeg3_MBAtab1[code].val; + } + + code -= 24; + mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab2[code].len); + + return val + mpeg3_MBAtab2[code].val; +} + +/* macroblock_type for pictures with spatial scalability */ + +static inline int mpeg3video_getsp_imb_type(mpeg3_slice_t *slice) +{ +// ### This looks wrong. +// slice_buffer is used without being initialised and slice is not used +// mpeg3_slice_buffer_t *slice_buffer = slice_buffer; +// I think this would make more sense and might be what is intended + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + unsigned int code = mpeg3slice_showbits(slice_buffer, 4); + if(!code) + { +/* fprintf(stderr,"mpeg3video_getsp_imb_type: invalid macroblock_type code\n"); */ + slice->fault = 1; + return 0; + } + + mpeg3slice_flushbits(slice_buffer, mpeg3_spIMBtab[code].len); + return mpeg3_spIMBtab[code].val; +} + +static inline int mpeg3video_getsp_pmb_type(mpeg3_slice_t *slice) +{ + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + int code = mpeg3slice_showbits(slice_buffer, 7); + if(code < 2) + { +/* fprintf(stderr,"mpeg3video_getsp_pmb_type: invalid macroblock_type code\n"); */ + slice->fault = 1; + return 0; + } + + if(code >= 16) + { + code >>= 3; + mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab0[code].len); + + return mpeg3_spPMBtab0[code].val; + } + + mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab1[code].len); + return mpeg3_spPMBtab1[code].val; +} + +static inline int mpeg3video_getsp_bmb_type(mpeg3_slice_t *slice) +{ + mpeg3_VLCtab_t *p; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + int code = mpeg3slice_showbits9(slice_buffer); + + if(code >= 64) + p = &mpeg3_spBMBtab0[(code >> 5) - 2]; + else + if(code >= 16) + p = &mpeg3_spBMBtab1[(code >> 2) - 4]; + else + if(code >= 8) + p = &mpeg3_spBMBtab2[code - 8]; + else + { +/* fprintf(stderr,"mpeg3video_getsp_bmb_type: invalid macroblock_type code\n"); */ + slice->fault = 1; + return 0; + } + + mpeg3slice_flushbits(slice_buffer, p->len); + return p->val; +} + +static inline int mpeg3video_get_imb_type(mpeg3_slice_t *slice) +{ + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + if(mpeg3slice_getbit(slice_buffer)) + { + return 1; + } + + if(!mpeg3slice_getbit(slice_buffer)) + { +/* fprintf(stderr,"mpeg3video_get_imb_type: invalid macroblock_type code\n"); */ + slice->fault = 1; + } + + return 17; +} + +static inline int mpeg3video_get_pmb_type(mpeg3_slice_t *slice) +{ + int code; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + + if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8) + { + code >>= 3; + mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab0[code].len); + return mpeg3_PMBtab0[code].val; + } + + if(code == 0) + { +/* fprintf(stderr,"mpeg3video_get_pmb_type: invalid macroblock_type code\n"); */ + slice->fault = 1; + return 0; + } + + mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab1[code].len); + return mpeg3_PMBtab1[code].val; +} + +static inline int mpeg3video_get_bmb_type(mpeg3_slice_t *slice) +{ + int code; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + + if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8) + { + code >>= 2; + mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab0[code].len); + return mpeg3_BMBtab0[code].val; + } + + if(code == 0) + { +/* fprintf(stderr,"mpeg3video_get_bmb_type: invalid macroblock_type code\n"); */ + slice->fault = 1; + return 0; + } + + mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab1[code].len); + + return mpeg3_BMBtab1[code].val; +} + +static inline int mpeg3video_get_dmb_type(mpeg3_slice_t *slice) +{ + if(!mpeg3slice_getbit(slice->slice_buffer)) + { +/* fprintf(stderr,"mpeg3video_get_dmb_type: invalid macroblock_type code\n"); */ + slice->fault=1; + } + + return 1; +} + + +static inline int mpeg3video_get_snrmb_type(mpeg3_slice_t *slice) +{ + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + int code = mpeg3slice_showbits(slice_buffer, 3); + + if(code == 0) + { +/* fprintf(stderr,"mpeg3video_get_snrmb_type: invalid macroblock_type code\n"); */ + slice->fault = 1; + return 0; + } + + mpeg3slice_flushbits(slice_buffer, mpeg3_SNRMBtab[code].len); + return mpeg3_SNRMBtab[code].val; +} + +int mpeg3video_get_mb_type(mpeg3_slice_t *slice, mpeg3video_t *video) +{ + if(video->scalable_mode == SC_SNR) + { + return mpeg3video_get_snrmb_type(slice); + } + else + { + switch(video->pict_type) + { + case I_TYPE: return video->pict_scal ? mpeg3video_getsp_imb_type(slice) : mpeg3video_get_imb_type(slice); + case P_TYPE: return video->pict_scal ? mpeg3video_getsp_pmb_type(slice) : mpeg3video_get_pmb_type(slice); + case B_TYPE: return video->pict_scal ? mpeg3video_getsp_bmb_type(slice) : mpeg3video_get_bmb_type(slice); + case D_TYPE: return mpeg3video_get_dmb_type(slice); + default: + /*fprintf(stderr, "mpeg3video_getmbtype: unknown coding type\n"); */ + break; +/* MPEG-1 only, not implemented */ + } + } + + return 0; +} + +int mpeg3video_macroblock_modes(mpeg3_slice_t *slice, + mpeg3video_t *video, + int *pmb_type, + int *pstwtype, + int *pstwclass, + int *pmotion_type, + int *pmv_count, + int *pmv_format, + int *pdmv, + int *pmvscale, + int *pdct_type) +{ + int mb_type; + int stwtype, stwcode, stwclass; + int motion_type = 0, mv_count, mv_format, dmv, mvscale; + int dct_type; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + static unsigned char stwc_table[3][4] + = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} }; + static unsigned char stwclass_table[9] + = {0, 1, 2, 1, 1, 2, 3, 3, 4}; + +/* get macroblock_type */ + mb_type = mpeg3video_get_mb_type(slice, video); + + if(slice->fault) return 1; + +/* get spatial_temporal_weight_code */ + if(mb_type & MB_WEIGHT) + { + if(video->stwc_table_index == 0) + stwtype = 4; + else + { + stwcode = mpeg3slice_getbits2(slice_buffer); + stwtype = stwc_table[video->stwc_table_index - 1][stwcode]; + } + } + else + stwtype = (mb_type & MB_CLASS4) ? 8 : 0; + +/* derive spatial_temporal_weight_class (Table 7-18) */ + stwclass = stwclass_table[stwtype]; + +/* get frame/field motion type */ + if(mb_type & (MB_FORWARD | MB_BACKWARD)) + { + if(video->pict_struct == FRAME_PICTURE) + { +/* frame_motion_type */ + motion_type = video->frame_pred_dct ? MC_FRAME : mpeg3slice_getbits2(slice_buffer); + } + else + { +/* field_motion_type */ + motion_type = mpeg3slice_getbits2(slice_buffer); + } + } + else + if((mb_type & MB_INTRA) && video->conceal_mv) + { +/* concealment motion vectors */ + motion_type = (video->pict_struct == FRAME_PICTURE) ? MC_FRAME : MC_FIELD; + } + +/* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */ + if(video->pict_struct == FRAME_PICTURE) + { + mv_count = (motion_type == MC_FIELD && stwclass < 2) ? 2 : 1; + mv_format = (motion_type == MC_FRAME) ? MV_FRAME : MV_FIELD; + } + else + { + mv_count = (motion_type == MC_16X8) ? 2 : 1; + mv_format = MV_FIELD; + } + + dmv = (motion_type == MC_DMV); /* dual prime */ + +/* field mv predictions in frame pictures have to be scaled */ + mvscale = ((mv_format == MV_FIELD) && (video->pict_struct == FRAME_PICTURE)); + +/* get dct_type (frame DCT / field DCT) */ + dct_type = (video->pict_struct == FRAME_PICTURE) && + (!video->frame_pred_dct) && + (mb_type & (MB_PATTERN | MB_INTRA)) ? + mpeg3slice_getbit(slice_buffer) : 0; + +/* return values */ + *pmb_type = mb_type; + *pstwtype = stwtype; + *pstwclass = stwclass; + *pmotion_type = motion_type; + *pmv_count = mv_count; + *pmv_format = mv_format; + *pdmv = dmv; + *pmvscale = mvscale; + *pdct_type = dct_type; + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/mmxidct.S b/core/multimedia/opieplayer/libmpeg3/video/mmxidct.S new file mode 100644 index 0000000..9c3bebe --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mmxidct.S @@ -0,0 +1,675 @@ +/* + * the input data is tranposed and each 16 bit element in the 8x8 matrix + * is left aligned: + * for example in 11...1110000 format + * If the iDCT is of I macroblock then 0.5 needs to be added to the;DC Component + * (element[0][0] of the matrix) + */ + +/* extrn re_matrix */ + +/* constants */ + +.data + .align 16 + .type preSC, @object +preSC: .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520 + .short 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270 + .short 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906 + .short 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315 + .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520 + .short 12873, 17855, 16819, 15137, 25746, 20228, 13933, 7103 + .short 17734, 24598, 23170, 20853, 17734, 13933, 9597, 4892 + .short 18081, 25080, 23624, 21261, 18081, 14206, 9785, 4988 + .size preSC, 128 + .align 8 + .type x0005000200010001, @object + .size x0005000200010001, 8 +x0005000200010001: + .long 0x00010001, 0x00050002 + .align 8 + .type x0040000000000000, @object + .size x0040000000000000, 8 +x0040000000000000: + .long 0, 0x00400000 + .align 8 + .type x5a825a825a825a82, @object + .size x5a825a825a825a82, 8 +x5a825a825a825a82: + .long 0x5a825a82, 0x5a825a82 + .align 8 + .type x539f539f539f539f, @object + .size x539f539f539f539f, 8 +x539f539f539f539f: + .long 0x539f539f, 0x539f539f + .align 8 + .type x4546454645464546, @object + .size x4546454645464546, 8 +x4546454645464546: + .long 0x45464546, 0x45464546 + .align 8 + .type x61f861f861f861f8, @object + .size x61f861f861f861f8, 8 +x61f861f861f861f8: + .long 0x61f861f8, 0x61f861f8 +/* Static variables */ + .align 8 + .type x0, @object + .size x0, 8 +x0: + .long 0, 0 +/* Procedure */ + + + .align 8 +.text + .align 4 +.globl IDCT_mmx + .type IDCT_mmx, @function +IDCT_mmx: + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %ecx + pushl %edx + pushl %esi + pushl %edi + + pushl $0 /* allocate the temp variables */ + pushl $0 + pushl $0 + pushl $0 + pushl $0 + pushl $0 + pushl $0 + pushl $0 + + movl 8(%ebp), %esi /* source matrix */ + leal preSC, %ecx +/* column 0: even part + * use V4, V12, V0, V8 to produce V22..V25 + */ + movq 8*12(%ecx), %mm0 /* maybe the first mul can be done together */ + /* with the dequantization in iHuff module */ + pmulhw 8*12(%esi), %mm0 /* V12 */ + movq 8*4(%ecx), %mm1 + pmulhw 8*4(%esi), %mm1 /* V4 */ + movq (%ecx), %mm3 + psraw $1, %mm0 /* t64=t66 */ + pmulhw (%esi), %mm3 /* V0 */ + movq 8*8(%ecx), %mm5 /* duplicate V4 */ + movq %mm1, %mm2 /* added 11/1/96 */ + pmulhw 8*8(%esi),%mm5 /* V8 */ + psubsw %mm0, %mm1 /* V16 */ + pmulhw x5a825a825a825a82, %mm1 /* 23170 ->V18 */ + paddsw %mm0, %mm2 /* V17 */ + movq %mm2, %mm0 /* duplicate V17 */ + psraw $1, %mm2 /* t75=t82 */ + psraw $2, %mm0 /* t72 */ + movq %mm3, %mm4 /* duplicate V0 */ + paddsw %mm5, %mm3 /* V19 */ + psubsw %mm5, %mm4 /* V20 ;mm5 free */ +/* moved from the block below */ + movq 8*10(%ecx), %mm7 + psraw $1, %mm3 /* t74=t81 */ + movq %mm3, %mm6 /* duplicate t74=t81 */ + psraw $2, %mm4 /* t77=t79 */ + psubsw %mm0, %mm1 /* V21 ; mm0 free */ + paddsw %mm2, %mm3 /* V22 */ + movq %mm1, %mm5 /* duplicate V21 */ + paddsw %mm4, %mm1 /* V23 */ + movq %mm3, 8*4(%esi) /* V22 */ + psubsw %mm5, %mm4 /* V24; mm5 free */ + movq %mm1, 8*12(%esi) /* V23 */ + psubsw %mm2, %mm6 /* V25; mm2 free */ + movq %mm4, (%esi) /* V24 */ +/* keep mm6 alive all along the next block */ + /* movq %mm6, 8*8(%esi) V25 */ +/* column 0: odd part + * use V2, V6, V10, V14 to produce V31, V39, V40, V41 + */ +/* moved above: movq 8*10(%ecx), %mm7 */ + + pmulhw 8*10(%esi), %mm7 /* V10 */ + movq 8*6(%ecx), %mm0 + pmulhw 8*6(%esi), %mm0 /* V6 */ + movq 8*2(%ecx), %mm5 + movq %mm7, %mm3 /* duplicate V10 */ + pmulhw 8*2(%esi), %mm5 /* V2 */ + movq 8*14(%ecx), %mm4 + psubsw %mm0, %mm7 /* V26 */ + pmulhw 8*14(%esi), %mm4 /* V14 */ + paddsw %mm0, %mm3 /* V29 ; free mm0 */ + movq %mm7, %mm1 /* duplicate V26 */ + psraw $1, %mm3 /* t91=t94 */ + pmulhw x539f539f539f539f,%mm7 /* V33 */ + psraw $1, %mm1 /* t96 */ + movq %mm5, %mm0 /* duplicate V2 */ + psraw $2, %mm4 /* t85=t87 */ + paddsw %mm4,%mm5 /* V27 */ + psubsw %mm4, %mm0 /* V28 ; free mm4 */ + movq %mm0, %mm2 /* duplicate V28 */ + psraw $1, %mm5 /* t90=t93 */ + pmulhw x4546454645464546,%mm0 /* V35 */ + psraw $1, %mm2 /* t97 */ + movq %mm5, %mm4 /* duplicate t90=t93 */ + psubsw %mm2, %mm1 /* V32 ; free mm2 */ + pmulhw x61f861f861f861f8,%mm1 /* V36 */ + psllw $1, %mm7 /* t107 */ + paddsw %mm3, %mm5 /* V31 */ + psubsw %mm3, %mm4 /* V30 ; free mm3 */ + pmulhw x5a825a825a825a82,%mm4 /* V34 */ + nop + psubsw %mm1, %mm0 /* V38 */ + psubsw %mm7, %mm1 /* V37 ; free mm7 */ + psllw $1, %mm1 /* t114 */ +/* move from the next block */ + movq %mm6, %mm3 /* duplicate V25 */ +/* move from the next block */ + movq 8*4(%esi), %mm7 /* V22 */ + psllw $1, %mm0 /* t110 */ + psubsw %mm5, %mm0 /* V39 (mm5 needed for next block) */ + psllw $2, %mm4 /* t112 */ +/* moved from the next block */ + movq 8*12(%esi), %mm2 /* V23 */ + psubsw %mm0, %mm4 /* V40 */ + paddsw %mm4, %mm1 /* V41; free mm0 */ +/* moved from the next block */ + psllw $1, %mm2 /* t117=t125 */ +/* column 0: output butterfly */ +/* moved above: + * movq %mm6, %mm3 duplicate V25 + * movq 8*4(%esi), %mm7 V22 + * movq 8*12(%esi), %mm2 V23 + * psllw $1, %mm2 t117=t125 + */ + psubsw %mm1, %mm6 /* tm6 */ + paddsw %mm1, %mm3 /* tm8; free mm1 */ + movq %mm7, %mm1 /* duplicate V22 */ + paddsw %mm5, %mm7 /* tm0 */ + movq %mm3, 8*8(%esi) /* tm8; free mm3 */ + psubsw %mm5, %mm1 /* tm14; free mm5 */ + movq %mm6, 8*6(%esi) /* tm6; free mm6 */ + movq %mm2, %mm3 /* duplicate t117=t125 */ + movq (%esi), %mm6 /* V24 */ + paddsw %mm0, %mm2 /* tm2 */ + movq %mm7, (%esi) /* tm0; free mm7 */ + psubsw %mm0, %mm3 /* tm12; free mm0 */ + movq %mm1, 8*14(%esi) /* tm14; free mm1 */ + psllw $1, %mm6 /* t119=t123 */ + movq %mm2, 8*2(%esi) /* tm2; free mm2 */ + movq %mm6, %mm0 /* duplicate t119=t123 */ + movq %mm3, 8*12(%esi) /* tm12; free mm3 */ + paddsw %mm4, %mm6 /* tm4 */ +/* moved from next block */ + movq 8*5(%ecx), %mm1 + psubsw %mm4, %mm0 /* tm10; free mm4 */ +/* moved from next block */ + pmulhw 8*5(%esi), %mm1 /* V5 */ + movq %mm6, 8*4(%esi) /* tm4; free mm6 */ + movq %mm0, 8*10(%esi) /* tm10; free mm0 */ +/* column 1: even part + * use V5, V13, V1, V9 to produce V56..V59 + */ +/* moved to prev block: + * movq 8*5(%ecx), %mm1 + * pmulhw 8*5(%esi), %mm1 V5 + */ + movq 8*13(%ecx), %mm7 + psllw $1, %mm1 /* t128=t130 */ + pmulhw 8*13(%esi), %mm7 /* V13 */ + movq %mm1, %mm2 /* duplicate t128=t130 */ + movq 8(%ecx), %mm3 + pmulhw 8(%esi), %mm3 /* V1 */ + movq 8*9(%ecx), %mm5 + psubsw %mm7, %mm1 /* V50 */ + pmulhw 8*9(%esi), %mm5 /* V9 */ + paddsw %mm7, %mm2 /* V51 */ + pmulhw x5a825a825a825a82, %mm1 /* 23170 ->V52 */ + movq %mm2, %mm6 /* duplicate V51 */ + psraw $1, %mm2 /* t138=t144 */ + movq %mm3, %mm4 /* duplicate V1 */ + psraw $2, %mm6 /* t136 */ + paddsw %mm5, %mm3 /* V53 */ + psubsw %mm5, %mm4 /* V54 ;mm5 free */ + movq %mm3, %mm7 /* duplicate V53 */ +/* moved from next block */ + movq 8*11(%ecx), %mm0 + psraw $1, %mm4 /* t140=t142 */ + psubsw %mm6, %mm1 /* V55 ; mm6 free */ + paddsw %mm2, %mm3 /* V56 */ + movq %mm4, %mm5 /* duplicate t140=t142 */ + paddsw %mm1, %mm4 /* V57 */ + movq %mm3, 8*5(%esi) /* V56 */ + psubsw %mm1, %mm5 /* V58; mm1 free */ + movq %mm4, 8*13(%esi) /* V57 */ + psubsw %mm2, %mm7 /* V59; mm2 free */ + movq %mm5, 8*9(%esi) /* V58 */ +/* keep mm7 alive all along the next block + * movq %mm7, 8(%esi) V59 + * moved above + * movq 8*11(%ecx), %mm0 + */ + pmulhw 8*11(%esi), %mm0 /* V11 */ + movq 8*7(%ecx), %mm6 + pmulhw 8*7(%esi), %mm6 /* V7 */ + movq 8*15(%ecx), %mm4 + movq %mm0, %mm3 /* duplicate V11 */ + pmulhw 8*15(%esi), %mm4 /* V15 */ + movq 8*3(%ecx), %mm5 + psllw $1, %mm6 /* t146=t152 */ + pmulhw 8*3(%esi), %mm5 /* V3 */ + paddsw %mm6, %mm0 /* V63 */ +/* note that V15 computation has a correction step: + * this is a 'magic' constant that rebiases the results to be closer to the + * expected result. this magic constant can be refined to reduce the error + * even more by doing the correction step in a later stage when the number + * is actually multiplied by 16 + */ + paddw x0005000200010001, %mm4 + psubsw %mm6, %mm3 /* V60 ; free mm6 */ + psraw $1, %mm0 /* t154=t156 */ + movq %mm3, %mm1 /* duplicate V60 */ + pmulhw x539f539f539f539f, %mm1 /* V67 */ + movq %mm5, %mm6 /* duplicate V3 */ + psraw $2, %mm4 /* t148=t150 */ + paddsw %mm4, %mm5 /* V61 */ + psubsw %mm4, %mm6 /* V62 ; free mm4 */ + movq %mm5, %mm4 /* duplicate V61 */ + psllw $1, %mm1 /* t169 */ + paddsw %mm0, %mm5 /* V65 -> result */ + psubsw %mm0, %mm4 /* V64 ; free mm0 */ + pmulhw x5a825a825a825a82, %mm4 /* V68 */ + psraw $1, %mm3 /* t158 */ + psubsw %mm6, %mm3 /* V66 */ + movq %mm5, %mm2 /* duplicate V65 */ + pmulhw x61f861f861f861f8, %mm3 /* V70 */ + psllw $1, %mm6 /* t165 */ + pmulhw x4546454645464546, %mm6 /* V69 */ + psraw $1, %mm2 /* t172 */ +/* moved from next block */ + movq 8*5(%esi), %mm0 /* V56 */ + psllw $1, %mm4 /* t174 */ +/* moved from next block */ + psraw $1, %mm0 /* t177=t188 */ + nop + psubsw %mm3, %mm6 /* V72 */ + psubsw %mm1, %mm3 /* V71 ; free mm1 */ + psubsw %mm2, %mm6 /* V73 ; free mm2 */ +/* moved from next block */ + psraw $1, %mm5 /* t178=t189 */ + psubsw %mm6, %mm4 /* V74 */ +/* moved from next block */ + movq %mm0, %mm1 /* duplicate t177=t188 */ + paddsw %mm4, %mm3 /* V75 */ +/* moved from next block */ + paddsw %mm5, %mm0 /* tm1 */ +/* location + * 5 - V56 + * 13 - V57 + * 9 - V58 + * X - V59, mm7 + * X - V65, mm5 + * X - V73, mm6 + * X - V74, mm4 + * X - V75, mm3 + * free mm0, mm1 & mm2 + * moved above + * movq 8*5(%esi), %mm0 V56 + * psllw $1, %mm0 t177=t188 ! new !! + * psllw $1, %mm5 t178=t189 ! new !! + * movq %mm0, %mm1 duplicate t177=t188 + * paddsw %mm5, %mm0 tm1 + */ + movq 8*13(%esi), %mm2 /* V57 */ + psubsw %mm5, %mm1 /* tm15; free mm5 */ + movq %mm0, 8(%esi) /* tm1; free mm0 */ + psraw $1, %mm7 /* t182=t184 ! new !! */ +/* save the store as used directly in the transpose + * movq %mm1, 120(%esi) tm15; free mm1 + */ + movq %mm7, %mm5 /* duplicate t182=t184 */ + psubsw %mm3, %mm7 /* tm7 */ + paddsw %mm3, %mm5 /* tm9; free mm3 */ + movq 8*9(%esi), %mm0 /* V58 */ + movq %mm2, %mm3 /* duplicate V57 */ + movq %mm7, 8*7(%esi) /* tm7; free mm7 */ + psubsw %mm6, %mm3 /* tm13 */ + paddsw %mm6, %mm2 /* tm3 ; free mm6 */ +/* moved up from the transpose */ + movq %mm3, %mm7 +/* moved up from the transpose */ + punpcklwd %mm1, %mm3 + movq %mm0, %mm6 /* duplicate V58 */ + movq %mm2, 8*3(%esi) /* tm3; free mm2 */ + paddsw %mm4, %mm0 /* tm5 */ + psubsw %mm4, %mm6 /* tm11; free mm4 */ +/* moved up from the transpose */ + punpckhwd %mm1, %mm7 + movq %mm0, 8*5(%esi) /* tm5; free mm0 */ +/* moved up from the transpose */ + movq %mm5, %mm2 +/* transpose - M4 part + * --------- --------- + * | M1 | M2 | | M1'| M3'| + * --------- --> --------- + * | M3 | M4 | | M2'| M4'| + * --------- --------- + * Two alternatives: use full mmword approach so the following code can be + * scheduled before the transpose is done without stores, or use the faster + * half mmword stores (when possible) + */ + movd %mm3, 8*9+4(%esi) /* MS part of tmt9 */ + punpcklwd %mm6, %mm5 + movd %mm7, 8*13+4(%esi) /* MS part of tmt13 */ + punpckhwd %mm6, %mm2 + movd %mm5, 8*9(%esi) /* LS part of tmt9 */ + punpckhdq %mm3, %mm5 /* free mm3 */ + movd %mm2, 8*13(%esi) /* LS part of tmt13 */ + punpckhdq %mm7, %mm2 /* free mm7 */ +/* moved up from the M3 transpose */ + movq 8*8(%esi), %mm0 +/* moved up from the M3 transpose */ + movq 8*10(%esi), %mm1 +/* moved up from the M3 transpose */ + movq %mm0, %mm3 +/* shuffle the rest of the data, and write it with 2 mmword writes */ + movq %mm5, 8*11(%esi) /* tmt11 */ +/* moved up from the M3 transpose */ + punpcklwd %mm1, %mm0 + movq %mm2, 8*15(%esi) /* tmt15 */ +/* moved up from the M3 transpose */ + punpckhwd %mm1, %mm3 +/* transpose - M3 part + * moved up to previous code section + * movq 8*8(%esi), %mm0 + * movq 8*10(%esi), %mm1 + * movq %mm0, %mm3 + * punpcklwd %mm1, %mm0 + * punpckhwd %mm1, %mm3 + */ + movq 8*12(%esi), %mm6 + movq 8*14(%esi), %mm4 + movq %mm6, %mm2 +/* shuffle the data and write the lower parts of the transposed in 4 dwords */ + punpcklwd %mm4, %mm6 + movq %mm0, %mm1 + punpckhdq %mm6, %mm1 + movq %mm3, %mm7 + punpckhwd %mm4, %mm2 /* free mm4 */ + punpckldq %mm6, %mm0 /* free mm6 */ +/* moved from next block */ + movq 8*13(%esi), %mm4 /* tmt13 */ + punpckldq %mm2, %mm3 + punpckhdq %mm2, %mm7 /* free mm2 */ +/* moved from next block */ + movq %mm3, %mm5 /* duplicate tmt5 */ +/* column 1: even part (after transpose) +* moved above +* movq %mm3, %mm5 duplicate tmt5 +* movq 8*13(%esi), %mm4 tmt13 +*/ + psubsw %mm4, %mm3 /* V134 */ + pmulhw x5a825a825a825a82, %mm3 /* 23170 ->V136 */ + movq 8*9(%esi), %mm6 /* tmt9 */ + paddsw %mm4, %mm5 /* V135 ; mm4 free */ + movq %mm0, %mm4 /* duplicate tmt1 */ + paddsw %mm6, %mm0 /* V137 */ + psubsw %mm6, %mm4 /* V138 ; mm6 free */ + psllw $2, %mm3 /* t290 */ + psubsw %mm5, %mm3 /* V139 */ + movq %mm0, %mm6 /* duplicate V137 */ + paddsw %mm5, %mm0 /* V140 */ + movq %mm4, %mm2 /* duplicate V138 */ + paddsw %mm3, %mm2 /* V141 */ + psubsw %mm3, %mm4 /* V142 ; mm3 free */ + movq %mm0, 8*9(%esi) /* V140 */ + psubsw %mm5, %mm6 /* V143 ; mm5 free */ +/* moved from next block */ + movq 8*11(%esi), %mm0 /* tmt11 */ + movq %mm2, 8*13(%esi) /* V141 */ +/* moved from next block */ + movq %mm0, %mm2 /* duplicate tmt11 */ +/* column 1: odd part (after transpose) */ +/* moved up to the prev block + * movq 8*11(%esi), %mm0 tmt11 + * movq %mm0, %mm2 duplicate tmt11 + */ + movq 8*15(%esi), %mm5 /* tmt15 */ + psubsw %mm7, %mm0 /* V144 */ + movq %mm0, %mm3 /* duplicate V144 */ + paddsw %mm7, %mm2 /* V147 ; free mm7 */ + pmulhw x539f539f539f539f, %mm0 /* 21407-> V151 */ + movq %mm1, %mm7 /* duplicate tmt3 */ + paddsw %mm5, %mm7 /* V145 */ + psubsw %mm5, %mm1 /* V146 ; free mm5 */ + psubsw %mm1, %mm3 /* V150 */ + movq %mm7, %mm5 /* duplicate V145 */ + pmulhw x4546454645464546, %mm1 /* 17734-> V153 */ + psubsw %mm2, %mm5 /* V148 */ + pmulhw x61f861f861f861f8, %mm3 /* 25080-> V154 */ + psllw $2, %mm0 /* t311 */ + pmulhw x5a825a825a825a82, %mm5 /* 23170-> V152 */ + paddsw %mm2, %mm7 /* V149 ; free mm2 */ + psllw $1, %mm1 /* t313 */ + nop /* without the nop - freeze here for one clock */ + movq %mm3, %mm2 /* duplicate V154 */ + psubsw %mm0, %mm3 /* V155 ; free mm0 */ + psubsw %mm2, %mm1 /* V156 ; free mm2 */ +/* moved from the next block */ + movq %mm6, %mm2 /* duplicate V143 */ +/* moved from the next block */ + movq 8*13(%esi), %mm0 /* V141 */ + psllw $1, %mm1 /* t315 */ + psubsw %mm7, %mm1 /* V157 (keep V149) */ + psllw $2, %mm5 /* t317 */ + psubsw %mm1, %mm5 /* V158 */ + psllw $1, %mm3 /* t319 */ + paddsw %mm5, %mm3 /* V159 */ +/* column 1: output butterfly (after transform) + * moved to the prev block + * movq %mm6, %mm2 duplicate V143 + * movq 8*13(%esi), %mm0 V141 + */ + psubsw %mm3, %mm2 /* V163 */ + paddsw %mm3, %mm6 /* V164 ; free mm3 */ + movq %mm4, %mm3 /* duplicate V142 */ + psubsw %mm5, %mm4 /* V165 ; free mm5 */ + movq %mm2, (%esp) /* out7 */ + psraw $4, %mm6 + psraw $4, %mm4 + paddsw %mm5, %mm3 /* V162 */ + movq 8*9(%esi), %mm2 /* V140 */ + movq %mm0, %mm5 /* duplicate V141 */ +/* in order not to perculate this line up, + * we read 72(%esi) very near to this location + */ + movq %mm6, 8*9(%esi) /* out9 */ + paddsw %mm1, %mm0 /* V161 */ + movq %mm3, 8(%esp) /* out5 */ + psubsw %mm1, %mm5 /* V166 ; free mm1 */ + movq %mm4, 8*11(%esi) /* out11 */ + psraw $4, %mm5 + movq %mm0, 16(%esp) /* out3 */ + movq %mm2, %mm4 /* duplicate V140 */ + movq %mm5, 8*13(%esi) /* out13 */ + paddsw %mm7, %mm2 /* V160 */ +/* moved from the next block */ + movq 8(%esi), %mm0 + psubsw %mm7, %mm4 /* V167 ; free mm7 */ +/* moved from the next block */ + movq 8*3(%esi), %mm7 + psraw $4, %mm4 + movq %mm2, 24(%esp) /* out1 */ +/* moved from the next block */ + movq %mm0, %mm1 + movq %mm4, 8*15(%esi) /* out15 */ +/* moved from the next block */ + punpcklwd %mm7, %mm0 +/* transpose - M2 parts + * moved up to the prev block + * movq 8(%esi), %mm0 + * movq 8*3(%esi), %mm7 + * movq %mm0, %mm1 + * punpcklwd %mm7, %mm0 + */ + movq 8*5(%esi), %mm5 + punpckhwd %mm7, %mm1 + movq 8*7(%esi), %mm4 + movq %mm5, %mm3 +/* shuffle the data and write the lower parts of the trasposed in 4 dwords */ + movd %mm0, 8*8(%esi) /* LS part of tmt8 */ + punpcklwd %mm4, %mm5 + movd %mm1, 8*12(%esi) /* LS part of tmt12 */ + punpckhwd %mm4, %mm3 + movd %mm5, 8*8+4(%esi) /* MS part of tmt8 */ + punpckhdq %mm5, %mm0 /* tmt10 */ + movd %mm3, 8*12+4(%esi) /* MS part of tmt12 */ + punpckhdq %mm3, %mm1 /* tmt14 */ +/* transpose - M1 parts */ + movq (%esi), %mm7 + movq 8*2(%esi), %mm2 + movq %mm7, %mm6 + movq 8*4(%esi), %mm5 + punpcklwd %mm2, %mm7 + movq 8*6(%esi), %mm4 + punpckhwd %mm2, %mm6 /* free mm2 */ + movq %mm5, %mm3 + punpcklwd %mm4, %mm5 + punpckhwd %mm4, %mm3 /* free mm4 */ + movq %mm7, %mm2 + movq %mm6, %mm4 + punpckldq %mm5, %mm7 /* tmt0 */ + punpckhdq %mm5, %mm2 /* tmt2 ; free mm5 */ +/* shuffle the rest of the data, and write it with 2 mmword writes */ + punpckldq %mm3, %mm6 /* tmt4 */ +/* moved from next block */ + movq %mm2, %mm5 /* duplicate tmt2 */ + punpckhdq %mm3, %mm4 /* tmt6 ; free mm3 */ +/* moved from next block */ + movq %mm0, %mm3 /* duplicate tmt10 */ +/* column 0: odd part (after transpose) + *moved up to prev block + * movq %mm0, %mm3 duplicate tmt10 + * movq %mm2, %mm5 duplicate tmt2 + */ + psubsw %mm4, %mm0 /* V110 */ + paddsw %mm4, %mm3 /* V113 ; free mm4 */ + movq %mm0, %mm4 /* duplicate V110 */ + paddsw %mm1, %mm2 /* V111 */ + pmulhw x539f539f539f539f, %mm0 /* 21407-> V117 */ + psubsw %mm1, %mm5 /* V112 ; free mm1 */ + psubsw %mm5, %mm4 /* V116 */ + movq %mm2, %mm1 /* duplicate V111 */ + pmulhw x4546454645464546, %mm5 /* 17734-> V119 */ + psubsw %mm3, %mm2 /* V114 */ + pmulhw x61f861f861f861f8, %mm4 /* 25080-> V120 */ + paddsw %mm3, %mm1 /* V115 ; free mm3 */ + pmulhw x5a825a825a825a82, %mm2 /* 23170-> V118 */ + psllw $2, %mm0 /* t266 */ + movq %mm1, (%esi) /* save V115 */ + psllw $1, %mm5 /* t268 */ + psubsw %mm4, %mm5 /* V122 */ + psubsw %mm0, %mm4 /* V121 ; free mm0 */ + psllw $1, %mm5 /* t270 */ + psubsw %mm1, %mm5 /* V123 ; free mm1 */ + psllw $2, %mm2 /* t272 */ + psubsw %mm5, %mm2 /* V124 (keep V123) */ + psllw $1, %mm4 /* t274 */ + movq %mm5, 8*2(%esi) /* save V123 ; free mm5 */ + paddsw %mm2, %mm4 /* V125 (keep V124) */ +/* column 0: even part (after transpose) */ + movq 8*12(%esi), %mm0 /* tmt12 */ + movq %mm6, %mm3 /* duplicate tmt4 */ + psubsw %mm0, %mm6 /* V100 */ + paddsw %mm0, %mm3 /* V101 ; free mm0 */ + pmulhw x5a825a825a825a82, %mm6 /* 23170 ->V102 */ + movq %mm7, %mm5 /* duplicate tmt0 */ + movq 8*8(%esi), %mm1 /* tmt8 */ + paddsw %mm1, %mm7 /* V103 */ + psubsw %mm1, %mm5 /* V104 ; free mm1 */ + movq %mm7, %mm0 /* duplicate V103 */ + psllw $2, %mm6 /* t245 */ + paddsw %mm3, %mm7 /* V106 */ + movq %mm5, %mm1 /* duplicate V104 */ + psubsw %mm3, %mm6 /* V105 */ + psubsw %mm3, %mm0 /* V109; free mm3 */ + paddsw %mm6, %mm5 /* V107 */ + psubsw %mm6, %mm1 /* V108 ; free mm6 */ +/* column 0: output butterfly (after transform) */ + movq %mm1, %mm3 /* duplicate V108 */ + paddsw %mm2, %mm1 /* out4 */ + psraw $4, %mm1 + psubsw %mm2, %mm3 /* out10 ; free mm2 */ + psraw $4, %mm3 + movq %mm0, %mm6 /* duplicate V109 */ + movq %mm1, 8*4(%esi) /* out4 ; free mm1 */ + psubsw %mm4, %mm0 /* out6 */ + movq %mm3, 8*10(%esi) /* out10 ; free mm3 */ + psraw $4, %mm0 + paddsw %mm4, %mm6 /* out8 ; free mm4 */ + movq %mm7, %mm1 /* duplicate V106 */ + movq %mm0, 8*6(%esi) /* out6 ; free mm0 */ + psraw $4, %mm6 + movq (%esi), %mm4 /* V115 */ + movq %mm6, 8*8(%esi) /* out8 ; free mm6 */ + movq %mm5, %mm2 /* duplicate V107 */ + movq 8*2(%esi), %mm3 /* V123 */ + paddsw %mm4, %mm7 /* out0 */ +/* moved up from next block */ + movq 16(%esp), %mm0 + psraw $4, %mm7 +/* moved up from next block */ + movq 8(%esp), %mm6 + psubsw %mm4, %mm1 /* out14 ; free mm4 */ + paddsw %mm3, %mm5 /* out2 */ + psraw $4, %mm1 + movq %mm7, (%esi) /* out0 ; free mm7 */ + psraw $4, %mm5 + movq %mm1, 8*14(%esi) /* out14 ; free mm1 */ + psubsw %mm3, %mm2 /* out12 ; free mm3 */ + movq %mm5, 8*2(%esi) /* out2 ; free mm5 */ + psraw $4, %mm2 +/* moved up to the prev block */ + movq (%esp), %mm4 +/* moved up to the prev block */ + psraw $4, %mm0 + movq %mm2, 8*12(%esi) /* out12 ; free mm2 */ +/* moved up to the prev block */ + psraw $4, %mm6 +/* move back the data to its correct place +* moved up to the prev block + * movq 16(%esp), %mm0 + * movq 8(%esp), %mm6 + * movq (%esp), %mm4 + * psraw $4, %mm0 + * psraw $4, %mm6 +*/ + movq 24(%esp), %mm1 + psraw $4, %mm4 + movq %mm0, 8*3(%esi) /* out3 */ + psraw $4, %mm1 + movq %mm6, 8*5(%esi) /* out5 */ + movq %mm4, 8*7(%esi) /* out7 */ + movq %mm1, 8(%esi) /* out1 */ + + popl %edi /* Pop off the temp variables */ + popl %edi + popl %edi + popl %edi + popl %edi + popl %edi + popl %edi + popl %edi + + popl %edi /* Pop off the old variables */ + popl %esi + popl %edx + popl %ecx + popl %ebx + movl %ebp, %esp + popl %ebp + + ret +.Lfe1: + .size IDCT_mmx,.Lfe1-IDCT_mmx diff --git a/core/multimedia/opieplayer/libmpeg3/video/mmxtest.c b/core/multimedia/opieplayer/libmpeg3/video/mmxtest.c new file mode 100644 index 0000000..567f139 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mmxtest.c @@ -0,0 +1,35 @@ +#include "../libmpeg3.h" +#include "../mpeg3protos.h" + +#include +#include + +int mpeg3_mmx_test() +{ + int result = 0; + FILE *proc; + char string[MPEG3_STRLEN]; + + +#ifdef HAVE_MMX + if(!(proc = fopen(MPEG3_PROC_CPUINFO, "r"))) + { + return 0; + } + + while(!feof(proc)) + { + fgets(string, MPEG3_STRLEN, proc); +/* Got the flags line */ + if(!strncmp(string, "flags", 5)) + { + char *needle; + needle = strstr(string, "mmx"); + if(!needle) return 0; + if(!strncmp(needle, "mmx", 3)) return 1; + } + } +#endif + + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/motion.c b/core/multimedia/opieplayer/libmpeg3/video/motion.c new file mode 100644 index 0000000..4d2f681 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/motion.c @@ -0,0 +1,230 @@ +#include "mpeg3video.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "vlc.h" + +#include + + +/* calculate motion vector component */ + +static inline void mpeg3video_calc_mv(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector) +{ + int lim = 16 << r_size; + int vec = full_pel_vector ? (*pred >> 1) : (*pred); + + if(motion_code > 0) + { + vec += ((motion_code - 1) << r_size) + motion_r + 1; + if(vec >= lim) vec -= lim + lim; + } + else + if(motion_code < 0) + { + vec -= ((-motion_code - 1) << r_size) + motion_r + 1; + if(vec < -lim) vec += lim + lim; + } + *pred = full_pel_vector ? (vec << 1) : vec; +} + + +/* +int *dmvector, * differential motion vector * +int mvx, int mvy * decoded mv components (always in field format) * +*/ +void mpeg3video_calc_dmv(mpeg3video_t *video, + int DMV[][2], + int *dmvector, + int mvx, + int mvy) +{ + if(video->pict_struct == FRAME_PICTURE) + { + if(video->topfirst) + { +/* vector for prediction of top field from bottom field */ + DMV[0][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0]; + DMV[0][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] - 1; + +/* vector for prediction of bottom field from top field */ + DMV[1][0] = ((3 * mvx + (mvx > 0)) >> 1) + dmvector[0]; + DMV[1][1] = ((3 * mvy + (mvy > 0)) >> 1) + dmvector[1] + 1; + } + else + { +/* vector for prediction of top field from bottom field */ + DMV[0][0] = ((3 * mvx + (mvx>0)) >> 1) + dmvector[0]; + DMV[0][1] = ((3 * mvy + (mvy>0)) >> 1) + dmvector[1] - 1; + +/* vector for prediction of bottom field from top field */ + DMV[1][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0]; + DMV[1][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] + 1; + } + } + else + { +/* vector for prediction from field of opposite 'parity' */ + DMV[0][0] = ((mvx + (mvx > 0)) >> 1) + dmvector[0]; + DMV[0][1] = ((mvy + (mvy > 0)) >> 1) + dmvector[1]; + +/* correct for vertical field shift */ + if(video->pict_struct == TOP_FIELD) + DMV[0][1]--; + else + DMV[0][1]++; + } +} + +static inline int mpeg3video_get_mv(mpeg3_slice_t *slice) +{ + int code; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + + if(mpeg3slice_getbit(slice_buffer)) + { + return 0; + } + + if((code = mpeg3slice_showbits9(slice_buffer)) >= 64) + { + code >>= 6; + mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab0[code].len); + return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab0[code].val : mpeg3_MVtab0[code].val; + } + + if(code >= 24) + { + code >>= 3; + mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab1[code].len); + return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab1[code].val : mpeg3_MVtab1[code].val; + } + + if((code -= 12) < 0) + { +/* fprintf(stdout,"mpeg3video_get_mv: invalid motion_vector code\n"); */ + slice->fault = 1; + return 1; + } + + mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab2[code].len); + return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab2[code].val : mpeg3_MVtab2[code].val; +} + +/* get differential motion vector (for dual prime prediction) */ + +static inline int mpeg3video_get_dmv(mpeg3_slice_t *slice) +{ + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + if(mpeg3slice_getbit(slice_buffer)) + { + return mpeg3slice_getbit(slice_buffer) ? -1 : 1; + } + else + { + return 0; + } +} + + + +/* get and decode motion vector and differential motion vector */ + +void mpeg3video_motion_vector(mpeg3_slice_t *slice, + mpeg3video_t *video, + int *PMV, + int *dmvector, + int h_r_size, + int v_r_size, + int dmv, + int mvscale, + int full_pel_vector) +{ + int motion_r; + int motion_code = mpeg3video_get_mv(slice); + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + + if(slice->fault) return; + motion_r = (h_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, h_r_size) : 0; + + mpeg3video_calc_mv(&PMV[0], h_r_size, motion_code, motion_r, full_pel_vector); + + if(dmv) dmvector[0] = mpeg3video_get_dmv(slice); + + motion_code = mpeg3video_get_mv(slice); + if(slice->fault) return; + motion_r = (v_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, v_r_size) : 0; + +/* DIV 2 */ + if(mvscale) PMV[1] >>= 1; + + mpeg3video_calc_mv(&PMV[1], v_r_size, motion_code, motion_r, full_pel_vector); + + if(mvscale) PMV[1] <<= 1; + if(dmv) dmvector[1] = mpeg3video_get_dmv(slice); +} + +int mpeg3video_motion_vectors(mpeg3_slice_t *slice, + mpeg3video_t *video, + int PMV[2][2][2], + int dmvector[2], + int mv_field_sel[2][2], + int s, + int mv_count, + int mv_format, + int h_r_size, + int v_r_size, + int dmv, + int mvscale) +{ + int result = 0; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + if(mv_count == 1) + { + if(mv_format == MV_FIELD && !dmv) + { + mv_field_sel[1][s] = mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer); + } + + mpeg3video_motion_vector(slice, + video, + PMV[0][s], + dmvector, + h_r_size, + v_r_size, + dmv, + mvscale, + 0); + if(slice->fault) return 1; + +/* update other motion vector predictors */ + PMV[1][s][0] = PMV[0][s][0]; + PMV[1][s][1] = PMV[0][s][1]; + } + else + { + mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer); + mpeg3video_motion_vector(slice, + video, + PMV[0][s], + dmvector, + h_r_size, + v_r_size, + dmv, + mvscale, + 0); + if(slice->fault) return 1; + + mv_field_sel[1][s] = mpeg3slice_getbit(slice_buffer); + mpeg3video_motion_vector(slice, + video, + PMV[1][s], + dmvector, + h_r_size, + v_r_size, + dmv, + mvscale, + 0); + if(slice->fault) return 1; + } + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c new file mode 100644 index 0000000..a9f113e --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c @@ -0,0 +1,597 @@ +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "mpeg3video.h" +#include "mpeg3videoprotos.h" +#include + +unsigned char mpeg3_zig_zag_scan_mmx[64] = +{ + 0*8+0 /* 0*/, 1*8+0 /* 1*/, 0*8+1 /* 8*/, 0*8+2 /*16*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 3*8+0 /* 3*/, 2*8+1 /*10*/, + 1*8+2 /*17*/, 0*8+3 /*24*/, 0*8+4 /*32*/, 1*8+3 /*25*/, 2*8+2 /*18*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 5*8+0 /* 5*/, + 4*8+1 /*12*/, 5*8+2 /*19*/, 2*8+3 /*26*/, 1*8+4 /*33*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 1*8+5 /*41*/, 2*8+4 /*34*/, + 3*8+3 /*27*/, 4*8+2 /*20*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 7*8+0 /* 7*/, 6*8+1 /*14*/, 5*8+2 /*21*/, 4*8+3 /*28*/, + 3*8+4 /*35*/, 2*8+5 /*42*/, 1*8+6 /*49*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 2*8+6 /*50*/, 3*8+5 /*43*/, 4*8+4 /*36*/, + 5*8+3 /*29*/, 6*8+2 /*22*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 6*8+3 /*30*/, 5*8+4 /*37*/, 4*8+5 /*44*/, 3*8+6 /*51*/, + 2*8+7 /*58*/, 3*8+7 /*59*/, 4*8+6 /*52*/, 5*8+5 /*45*/, 6*8+4 /*38*/, 7*8+3 /*31*/, 7*8+4 /*39*/, 6*8+5 /*46*/, + 7*8+6 /*53*/, 4*8+7 /*60*/, 5*8+7 /*61*/, 6*8+6 /*54*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 6*8+7 /*62*/, 7*8+7 /*63*/ +}; + +/* alternate scan */ +unsigned char mpeg3_alternate_scan_mmx[64] = +{ + 0*8+0 /*0 */, 0*8+1 /* 8*/, 0*8+2 /*16*/, 0*8+3 /*24*/, 1*8+0 /* 1*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 2*8+1 /*10*/, + 1*8+2 /*17*/, 1*8+3 /*25*/, 0*8+4 /*32*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 1*8+6 /*49*/, + 1*8+5 /*41*/, 1*8+4 /*33*/, 2*8+3 /*26*/, 2*8+2 /*18*/, 3*8+0 /* 3*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 4*8+1 /*12*/, + 3*8+2 /*19*/, 3*8+3 /*27*/, 2*8+4 /*34*/, 2*8+5 /*42*/, 2*8+6 /*50*/, 2*8+7 /*58*/, 3*8+4 /*35*/, 3*8+5 /*43*/, + 3*8+6 /*51*/, 3*8+7 /*59*/, 4*8+2 /*20*/, 4*8+3 /*28*/, 5*8+0 /* 5*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 6*8+1 /*14*/, + 5*8+2 /*21*/, 5*8+3 /*29*/, 4*8+4 /*36*/, 4*8+5 /*44*/, 4*8+6 /*52*/, 4*8+7 /*60*/, 5*8+4 /*37*/, 5*8+5 /*45*/, + 5*8+6 /*53*/, 5*8+7 /*61*/, 6*8+2 /*22*/, 6*8+3 /*30*/, 7*8+0 /* 7*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 7*8+3 /*31*/, + 6*8+4 /*38*/, 6*8+5 /*46*/, 6*8+6 /*54*/, 6*8+7 /*62*/, 7*8+4 /*39*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 7*8+6 /*63*/ +}; + + + +/* zig-zag scan */ +unsigned char mpeg3_zig_zag_scan_nommx[64] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 +}; + +/* alternate scan */ +unsigned char mpeg3_alternate_scan_nommx[64] = +{ + 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49, + 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43, + 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45, + 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63 +}; + +/* default intra quantization matrix */ +unsigned char mpeg3_default_intra_quantizer_matrix[64] = +{ + 8, 16, 19, 22, 26, 27, 29, 34, + 16, 16, 22, 24, 27, 29, 34, 37, + 19, 22, 26, 27, 29, 34, 34, 38, + 22, 22, 26, 27, 29, 34, 37, 40, + 22, 26, 27, 29, 32, 35, 40, 48, + 26, 27, 29, 32, 35, 40, 48, 58, + 26, 27, 29, 34, 38, 46, 56, 69, + 27, 29, 35, 38, 46, 56, 69, 83 +}; + +unsigned char mpeg3_non_linear_mquant_table[32] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 10, 12, 14, 16, 18, 20, 22, + 24, 28, 32, 36, 40, 44, 48, 52, + 56, 64, 72, 80, 88, 96, 104, 112 +}; + +double mpeg3_frame_rate_table[16] = +{ + 0.0, /* Pad */ + 24000.0/1001.0, /* Official frame rates */ + 24.0, + 25.0, + 30000.0/1001.0, + 30.0, + 50.0, + ((60.0*1000.0)/1001.0), + 60.0, + + 1, /* Unofficial economy rates */ + 5, + 10, + 12, + 15, + 0, + 0, +}; + +int mpeg3video_initdecoder(mpeg3video_t *video) +{ + int blk_cnt_tab[3] = {6, 8, 12}; + int cc; + int i; + long size[4], padding[2]; /* Size of Y, U, and V buffers */ + + if(!video->mpeg2) + { +/* force MPEG-1 parameters */ + video->prog_seq = 1; + video->prog_frame = 1; + video->pict_struct = FRAME_PICTURE; + video->frame_pred_dct = 1; + video->chroma_format = CHROMA420; + video->matrix_coefficients = 5; + } + +/* Get dimensions rounded to nearest multiple of coded macroblocks */ + video->mb_width = (video->horizontal_size + 15) / 16; + video->mb_height = (video->mpeg2 && !video->prog_seq) ? + (2 * ((video->vertical_size + 31) / 32)) : + ((video->vertical_size + 15) / 16); + video->coded_picture_width = 16 * video->mb_width; + video->coded_picture_height = 16 * video->mb_height; + video->chrom_width = (video->chroma_format == CHROMA444) ? + video->coded_picture_width : + (video->coded_picture_width >> 1); + video->chrom_height = (video->chroma_format != CHROMA420) ? + video->coded_picture_height : + (video->coded_picture_height >> 1); + video->blk_cnt = blk_cnt_tab[video->chroma_format - 1]; + +/* Get sizes of YUV buffers */ + padding[0] = 16 * video->coded_picture_width; + size[0] = video->coded_picture_width * video->coded_picture_height + padding[0] * 2; + + padding[1] = 16 * video->chrom_width; + size[1] = video->chrom_width * video->chrom_height + 2 * padding[1]; + + size[2] = (video->llw * video->llh); + size[3] = (video->llw * video->llh) / 4; + +/* Allocate contiguous fragments for YUV buffers for hardware YUV decoding */ + video->yuv_buffer[0] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1])); + video->yuv_buffer[1] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1])); + video->yuv_buffer[2] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1])); + + if(video->scalable_mode == SC_SPAT) + { + video->yuv_buffer[3] = (unsigned char*)calloc(1, size[2] + 2 * size[3]); + video->yuv_buffer[4] = (unsigned char*)calloc(1, size[2] + 2 * size[3]); + } + +/* Direct pointers to areas of contiguous fragments in YVU order per Microsoft */ + for(cc = 0; cc < 3; cc++) + { + video->llframe0[cc] = 0; + video->llframe1[cc] = 0; + video->newframe[cc] = 0; + } + + video->refframe[0] = video->yuv_buffer[0]; + video->oldrefframe[0] = video->yuv_buffer[1]; + video->auxframe[0] = video->yuv_buffer[2]; + video->refframe[2] = video->yuv_buffer[0] + size[0] + padding[0]; + video->oldrefframe[2] = video->yuv_buffer[1] + size[0] + padding[0]; + video->auxframe[2] = video->yuv_buffer[2] + size[0] + padding[0]; + video->refframe[1] = video->yuv_buffer[0] + size[0] + padding[0] + size[1] + padding[1]; + video->oldrefframe[1] = video->yuv_buffer[1] + size[0] + padding[0] + size[1] + padding[1]; + video->auxframe[1] = video->yuv_buffer[2] + size[0] + padding[0] + size[1] + padding[1]; + + if(video->scalable_mode == SC_SPAT) + { +/* this assumes lower layer is 4:2:0 */ + video->llframe0[0] = video->yuv_buffer[3] + padding[0] ; + video->llframe1[0] = video->yuv_buffer[4] + padding[0] ; + video->llframe0[2] = video->yuv_buffer[3] + padding[1] + size[2] ; + video->llframe1[2] = video->yuv_buffer[4] + padding[1] + size[2] ; + video->llframe0[1] = video->yuv_buffer[3] + padding[1] + size[2] + size[3]; + video->llframe1[1] = video->yuv_buffer[4] + padding[1] + size[2] + size[3]; + } + +/* Initialize the YUV tables for software YUV decoding */ + video->cr_to_r = (long*)malloc(sizeof(long) * 256); + video->cr_to_g = (long*)malloc(sizeof(long) * 256); + video->cb_to_g = (long*)malloc(sizeof(long) * 256); + video->cb_to_b = (long*)malloc(sizeof(long) * 256); + video->cr_to_r_ptr = video->cr_to_r + 128; + video->cr_to_g_ptr = video->cr_to_g + 128; + video->cb_to_g_ptr = video->cb_to_g + 128; + video->cb_to_b_ptr = video->cb_to_b + 128; + + for(i = -128; i < 128; i++) + { + video->cr_to_r_ptr[i] = (long)( 1.371 * 65536 * i); + video->cr_to_g_ptr[i] = (long)(-0.698 * 65536 * i); + video->cb_to_g_ptr[i] = (long)(-0.336 * 65536 * i); + video->cb_to_b_ptr[i] = (long)( 1.732 * 65536 * i); + } + + return 0; +} + +int mpeg3video_deletedecoder(mpeg3video_t *video) +{ + int i, padding; + + free(video->yuv_buffer[0]); + free(video->yuv_buffer[1]); + free(video->yuv_buffer[2]); + + if(video->llframe0[0]) + { + free(video->yuv_buffer[3]); + free(video->yuv_buffer[4]); + } + + free(video->cr_to_r); + free(video->cr_to_g); + free(video->cb_to_g); + free(video->cb_to_b); + return 0; +} + +void mpeg3video_init_scantables(mpeg3video_t *video) +{ +#ifdef HAVE_MMX + if(video->have_mmx) + { + video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_mmx; + video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_mmx; + } + else +#endif + { + video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_nommx; + video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_nommx; + } +} + +mpeg3video_t* mpeg3video_allocate_struct(mpeg3_t *file, mpeg3_vtrack_t *track) +{ + int i; + mpeg3video_t *video = (mpeg3video_t*)calloc(1, sizeof(mpeg3video_t)); + pthread_mutexattr_t mutex_attr; + + video->file = file; + video->track = track; + video->vstream = mpeg3bits_new_stream(file, track->demuxer); + video->last_number = -1; + +/* First frame is all green */ + video->framenum = -1; + video->have_mmx = file->have_mmx; + + video->percentage_seek = -1; + video->frame_seek = -1; + + mpeg3video_init_scantables(video); + mpeg3video_init_output(); + + pthread_mutexattr_init(&mutex_attr); + pthread_mutex_init(&(video->test_lock), &mutex_attr); + pthread_mutex_init(&(video->slice_lock), &mutex_attr); + return video; +} + +int mpeg3video_delete_struct(mpeg3video_t *video) +{ + int i; + mpeg3bits_delete_stream(video->vstream); + pthread_mutex_destroy(&(video->test_lock)); + pthread_mutex_destroy(&(video->slice_lock)); + if(video->x_table) + { + free(video->x_table); + free(video->y_table); + } + if(video->total_slice_decoders) + { + for(i = 0; i < video->total_slice_decoders; i++) + mpeg3_delete_slice_decoder(&video->slice_decoders[i]); + } + for(i = 0; i < video->slice_buffers_initialized; i++) + mpeg3_delete_slice_buffer(&(video->slice_buffers[i])); + + free(video); +} + + +int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes) +{ + int result = 0; + + if(mpeg3bits_eof(video->vstream)) result = 1; + + if(!result) result = mpeg3video_get_header(video, 0); + +//printf("frame type %d\n", video->pict_type); +/* skip_bframes is the number of bframes we can skip successfully. */ +/* This is in case a skipped B-frame is repeated and the second repeat happens */ +/* to be a B frame we need. */ + video->skip_bframes = skip_bframes; + + if(!result) + result = mpeg3video_getpicture(video, video->framenum); + +#ifdef HAVE_MMX + if(video->have_mmx) + __asm__ __volatile__ ("emms"); +#endif + + if(!result) + { + video->last_number = video->framenum; + video->framenum++; + } + return result; +} + +int* mpeg3video_get_scaletable(int input_w, int output_w) +{ + int *result = (int*)malloc(sizeof(int) * output_w); + float i; + float scale = (float)input_w / output_w; + for(i = 0; i < output_w; i++) + { + result[(int)i] = (int)(scale * i); + } + return result; +} + +/* Get the first frame read. */ +int mpeg3video_get_firstframe(mpeg3video_t *video) +{ + int result = 0; + if(video->framenum < 0) + { + video->repeat_count = video->current_repeat = 0; + result = mpeg3video_read_frame_backend(video, 0); + mpeg3bits_seek_byte(video->vstream, 0); + mpeg3video_match_refframes(video); + } + return result; +} + + +/* ======================================================================= */ +/* ENTRY POINTS */ +/* ======================================================================= */ + + + +mpeg3video_t* mpeg3video_new(mpeg3_t *file, mpeg3_vtrack_t *track) +{ + mpeg3video_t *video; + int result = 0; + + video = mpeg3video_allocate_struct(file, track); + result = mpeg3video_get_header(video, 1); + + if(!result) + { + int hour, minute, second, frame; + int gop_found; + + mpeg3video_initdecoder(video); + video->decoder_initted = 1; + track->width = video->horizontal_size; + track->height = video->vertical_size; + track->frame_rate = video->frame_rate; + +/* Get the length of the file from an elementary stream */ + if(file->is_video_stream) + { +/* Load the first GOP */ + mpeg3bits_seek_start(video->vstream); + result = mpeg3video_next_code(video->vstream, MPEG3_GOP_START_CODE); + if(!result) mpeg3bits_getbits(video->vstream, 32); + if(!result) result = mpeg3video_getgophdr(video); + + hour = video->gop_timecode.hour; + minute = video->gop_timecode.minute; + second = video->gop_timecode.second; + frame = video->gop_timecode.frame; + video->first_frame = (long)(hour * 3600 * video->frame_rate + + minute * 60 * video->frame_rate + + second * video->frame_rate + + frame); + +/* GOPs always have 16 frames */ + video->frames_per_gop = 16; + +/* Read the last GOP in the file by seeking backward. */ + mpeg3bits_seek_end(video->vstream); + mpeg3bits_start_reverse(video->vstream); + result = mpeg3video_prev_code(video->vstream, MPEG3_GOP_START_CODE); + mpeg3bits_start_forward(video->vstream); + mpeg3bits_getbits(video->vstream, 8); + if(!result) result = mpeg3video_getgophdr(video); + + hour = video->gop_timecode.hour; + minute = video->gop_timecode.minute; + second = video->gop_timecode.second; + frame = video->gop_timecode.frame; + + video->last_frame = (long)(hour * 3600 * video->frame_rate + + minute * 60 * video->frame_rate + + second * video->frame_rate + + frame); + +/* Count number of frames to end */ + while(!result) + { + result = mpeg3video_next_code(video->vstream, MPEG3_PICTURE_START_CODE); + if(!result) + { + mpeg3bits_getbyte_noptr(video->vstream); + video->last_frame++; + } + } + + track->total_frames = video->last_frame - video->first_frame + 1; + mpeg3bits_seek_start(video->vstream); + } + else + { +/* Gross approximation from a multiplexed file. */ + video->first_frame = 0; + track->total_frames = video->last_frame = + (long)(mpeg3demux_length(video->vstream->demuxer) * + video->frame_rate); + video->first_frame = 0; + } + + video->maxframe = track->total_frames; + mpeg3bits_seek_start(video->vstream); + } + else + { + mpeg3video_delete(video); + video = 0; + } + + return video; +} + +int mpeg3video_delete(mpeg3video_t *video) +{ + if(video->decoder_initted) + { + mpeg3video_deletedecoder(video); + } + mpeg3video_delete_struct(video); + return 0; +} + +int mpeg3video_set_cpus(mpeg3video_t *video, int cpus) +{ + return 0; +} + +int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx) +{ + video->have_mmx = use_mmx; + mpeg3video_init_scantables(video); + return 0; +} + +int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage) +{ + video->percentage_seek = percentage; + return 0; +} + +int mpeg3video_previous_frame(mpeg3video_t *video) +{ + if(mpeg3bits_tell_percentage(video->vstream) <= 0) return 1; + mpeg3bits_start_reverse(video->vstream); + mpeg3video_prev_code(video->vstream, MPEG3_PICTURE_START_CODE); + mpeg3bits_getbits_reverse(video->vstream, 32); + + if(mpeg3bits_bof(video->vstream)) mpeg3bits_seek_percentage(video->vstream, 0); + mpeg3bits_start_forward(video->vstream); + video->repeat_count = 0; + return 0; +} + +int mpeg3video_seek_frame(mpeg3video_t *video, long frame) +{ + video->frame_seek = frame; + return 0; +} + +/* Read all the way up to and including the next picture start code */ +int mpeg3video_read_raw(mpeg3video_t *video, unsigned char *output, long *size, long max_size) +{ + unsigned MPEG3_INT32 code = 0; + mpeg3_bits_t *vstream = video->vstream; + + *size = 0; + while(code != MPEG3_PICTURE_START_CODE && + code != MPEG3_SEQUENCE_END_CODE && + *size < max_size && + !mpeg3bits_eof(vstream)) + { + code <<= 8; + *output = mpeg3bits_getbyte_noptr(vstream); + code |= *output++; + (*size)++; + } + return mpeg3bits_eof(vstream); +} + +int mpeg3video_read_frame(mpeg3video_t *video, + long frame_number, + unsigned char **output_rows, + int in_x, + int in_y, + int in_w, + int in_h, + int out_w, + int out_h, + int color_model) +{ + int result = 0; + + video->want_yvu = 0; + video->output_rows = output_rows; + video->color_model = color_model; + +/* Get scaling tables */ + if(video->out_w != out_w || video->out_h != out_h || + video->in_w != in_w || video->in_h != in_h || + video->in_x != in_x || video->in_y != in_y) + { + if(video->x_table) + { + free(video->x_table); + free(video->y_table); + video->x_table = 0; + video->y_table = 0; + } + } + + video->out_w = out_w; + video->out_h = out_h; + video->in_w = in_w; + video->in_h = in_h; + video->in_x = in_x; + video->in_y = in_y; + + if(!video->x_table) + { + video->x_table = mpeg3video_get_scaletable(video->in_w, video->out_w); + video->y_table = mpeg3video_get_scaletable(video->in_h, video->out_h); + } + + mpeg3video_get_firstframe(video); + + if(!result) result = mpeg3video_seek(video); + + if(!result) result = mpeg3video_read_frame_backend(video, 0); + + if(video->output_src) mpeg3video_present_frame(video); + + video->percentage_seek = -1; + return result; +} + +int mpeg3video_read_yuvframe(mpeg3video_t *video, + long frame_number, + char *y_output, + char *u_output, + char *v_output, + int in_x, + int in_y, + int in_w, + int in_h) +{ + int result = 0; + + video->want_yvu = 1; + video->y_output = y_output; + video->u_output = u_output; + video->v_output = v_output; + video->in_x = in_x; + video->in_y = in_y; + video->in_w = in_w; + video->in_h = in_h; + + mpeg3video_get_firstframe(video); + + if(!result) result = mpeg3video_seek(video); + + if(!result) result = mpeg3video_read_frame_backend(video, 0); + + if(video->output_src) mpeg3video_present_frame(video); + + video->want_yvu = 0; + video->percentage_seek = -1; + return result; +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h new file mode 100644 index 0000000..2db62b0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h @@ -0,0 +1,180 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEGVIDEO_H +#define MPEGVIDEO_H + +#include "../bitstream.h" +#include "../mpeg3private.inc" +#include "idct.h" +#include "slice.h" +#include "../timecode.h" + +/* zig-zag scan */ +extern unsigned char mpeg3_zig_zag_scan_nommx[64]; +extern unsigned char mpeg3_zig_zag_scan_mmx[64]; + +/* alternate scan */ +extern unsigned char mpeg3_alternate_scan_nommx[64]; +extern unsigned char mpeg3_alternate_scan_mmx[64]; + +/* default intra quantization matrix */ +extern unsigned char mpeg3_default_intra_quantizer_matrix[64]; + +/* Frame rate table must agree with the one in the encoder */ +extern double mpeg3_frame_rate_table[16]; + +/* non-linear quantization coefficient table */ +extern unsigned char mpeg3_non_linear_mquant_table[32]; + +#define CHROMA420 1 /* chroma_format */ +#define CHROMA422 2 +#define CHROMA444 3 + +#define TOP_FIELD 1 /* picture structure */ +#define BOTTOM_FIELD 2 +#define FRAME_PICTURE 3 + +#define SEQ_ID 1 /* extension start code IDs */ +#define DISP_ID 2 +#define QUANT_ID 3 +#define SEQSCAL_ID 5 +#define PANSCAN_ID 7 +#define CODING_ID 8 +#define SPATSCAL_ID 9 +#define TEMPSCAL_ID 10 + +#define ERROR (-1) + +#define SC_NONE 0 /* scalable_mode */ +#define SC_DP 1 +#define SC_SPAT 2 +#define SC_SNR 3 +#define SC_TEMP 4 + +#define I_TYPE 1 /* picture coding type */ +#define P_TYPE 2 +#define B_TYPE 3 +#define D_TYPE 4 + +#define MB_INTRA 1 /* macroblock type */ +#define MB_PATTERN 2 +#define MB_BACKWARD 4 +#define MB_FORWARD 8 +#define MB_QUANT 16 +#define MB_WEIGHT 32 +#define MB_CLASS4 64 + +#define MC_FIELD 1 /* motion_type */ +#define MC_FRAME 2 +#define MC_16X8 2 +#define MC_DMV 3 + +#define MV_FIELD 0 /* mv_format */ +#define MV_FRAME 1 + +#define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0) + +/* Statically allocate as little as possible so a fake video struct */ +/* can be used for reading the GOP headers. */ + +struct mpeg3video_rec +{ + struct mpeg3_rec* file; + struct mpeg3_vtrack_rec* track; + +/* ================================= Seeking variables ========================= */ + mpeg3_bits_t *vstream; + int decoder_initted; + unsigned char **output_rows; /* Output frame buffer supplied by user */ + int in_x, in_y, in_w, in_h, out_w, out_h; /* Output dimensions */ + int *x_table, *y_table; /* Location of every output pixel in the input */ + int color_model; + int want_yvu; /* Want to return a YUV frame */ + char *y_output, *u_output, *v_output; /* Output pointers for a YUV frame */ + + mpeg3_slice_t slice_decoders[MPEG3_MAX_CPUS]; /* One slice decoder for every CPU */ + int total_slice_decoders; /* Total slice decoders in use */ + mpeg3_slice_buffer_t slice_buffers[MPEG3_MAX_CPUS]; /* Buffers for holding the slice data */ + int total_slice_buffers; /* Total buffers in the array to be decompressed */ + int slice_buffers_initialized; /* Total buffers initialized in the array */ + pthread_mutex_t slice_lock; /* Lock slice array while getting the next buffer */ + pthread_mutex_t test_lock; + + int blockreadsize; + long maxframe; /* Max value of frame num to read */ + double percentage_seek; /* Perform a percentage seek before the next frame is read */ + int frame_seek; /* Perform a frame seek before the next frame is read */ + long framenum; /* Number of the next frame to be decoded */ + long last_number; /* Last framenum rendered */ + int found_seqhdr; + long bitrate; + mpeg3_timecode_t gop_timecode; /* Timecode for the last GOP header read. */ + +/* These are only available from elementary streams. */ + long frames_per_gop; /* Frames per GOP after the first GOP. */ + long first_gop_frames; /* Frames in the first GOP. */ + long first_frame; /* Number of first frame stored in timecode */ + long last_frame; /* Last frame in file */ + +/* ================================= Compression variables ===================== */ +/* Malloced frame buffers. 2 refframes are swapped in and out. */ +/* while only 1 auxframe is used. */ + unsigned char *yuv_buffer[5]; /* Make YVU buffers contiguous for all frames */ + unsigned char *oldrefframe[3], *refframe[3], *auxframe[3]; + unsigned char *llframe0[3], *llframe1[3]; + unsigned char *mpeg3_zigzag_scan_table; + unsigned char *mpeg3_alternate_scan_table; +// Source for the next frame presentation + unsigned char **output_src; +/* Pointers to frame buffers. */ + unsigned char *newframe[3]; + int horizontal_size, vertical_size, mb_width, mb_height; + int coded_picture_width, coded_picture_height; + int chroma_format, chrom_width, chrom_height, blk_cnt; + int pict_type; + int forw_r_size, back_r_size, full_forw, full_back; + int prog_seq, prog_frame; + int h_forw_r_size, v_forw_r_size, h_back_r_size, v_back_r_size; + int dc_prec, pict_struct, topfirst, frame_pred_dct, conceal_mv; + int intravlc; + int repeatfirst; + int repeat_count; /* Number of times to repeat the current frame * 100 since floating point is impossible in MMX */ + int current_repeat; /* Number of times the current frame has been repeated * 100 */ + int secondfield; + int skip_bframes; + int stwc_table_index, llw, llh, hm, hn, vm, vn; + int lltempref, llx0, lly0, llprog_frame, llfieldsel; + int matrix_coefficients; + int framerate_code; + float frame_rate; + long *cr_to_r, *cr_to_g, *cb_to_g, *cb_to_b; + long *cr_to_r_ptr, *cr_to_g_ptr, *cb_to_g_ptr, *cb_to_b_ptr; + int have_mmx; + int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64]; + int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64]; + int mpeg2; + int qscale_type, altscan; /* picture coding extension */ + int pict_scal; /* picture spatial scalable extension */ + int scalable_mode; /* sequence scalable extension */ +}; + +typedef struct mpeg3video_rec mpeg3video_t; + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h b/core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h new file mode 100644 index 0000000..e48d6cd --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h @@ -0,0 +1,26 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEG3VIDEOPROTOS_H +#define MPEG3VIDEOPROTOS_H + +void mpeg3video_idct_conversion(short* block); +unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits); + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/video/output.c b/core/multimedia/opieplayer/libmpeg3/video/output.c new file mode 100644 index 0000000..919a0ff --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/output.c @@ -0,0 +1,993 @@ +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "mpeg3video.h" +#include + +static LONGLONG mpeg3_MMX_0 = 0L; +static unsigned long mpeg3_MMX_10w[] = {0x00100010, 0x00100010}; /*dd 00010 0010h, 000100010h */ +static unsigned long mpeg3_MMX_80w[] = {0x00800080, 0x00800080}; /*dd 00080 0080h, 000800080h */ + +static unsigned long mpeg3_MMX_00FFw[] = {0x00ff00ff, 0x00ff00ff}; /*dd 000FF 00FFh, 000FF00FFh */ + +static unsigned short mpeg3_MMX_Ublucoeff[] = {0x81, 0x81, 0x81, 0x81}; /*dd 00081 0081h, 000810081h */ +static unsigned short mpeg3_MMX_Vredcoeff[] = {0x66, 0x66, 0x66, 0x66}; /*dd 00066 0066h, 000660066h */ + +static unsigned short mpeg3_MMX_Ugrncoeff[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; /*dd 0FFE7 FFE7h, 0FFE7FFE7h */ +static unsigned short mpeg3_MMX_Vgrncoeff[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; /*dd 0FFCC FFCCh, 0FFCCFFCCh */ + +static unsigned short mpeg3_MMX_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a}; /*dd 0004A 004Ah, 0004A004Ah */ + +static unsigned short mpeg3_MMX_redmask[] = {0xf800, 0xf800, 0xf800, 0xf800}; /*dd 07c00 7c00h, 07c007c00h */ + +static unsigned short mpeg3_MMX_grnmask[] = {0x7e0, 0x7e0, 0x7e0, 0x7e0}; /*dd 003e0 03e0h, 003e003e0h */ + +static unsigned char mpeg3_601_to_rgb[256]; + +/* Algorithm */ +/* r = (int)(*y + 1.371 * (*cr - 128)); */ +/* g = (int)(*y - 0.698 * (*cr - 128) - 0.336 * (*cb - 128)); */ +/* b = (int)(*y + 1.732 * (*cb - 128)); */ + +#ifdef HAVE_MMX +inline void mpeg3video_rgb16_mmx(unsigned char *lum, + unsigned char *cr, + unsigned char *cb, + unsigned char *out, + int rows, + int cols, + int mod) +{ + unsigned short *row1; + int x; + unsigned char *y; + int col1; + + row1 = (unsigned short *)out; + col1 = cols + mod; + mod += cols + mod; + mod *= 2; + y = lum + cols * rows; + x = 0; + + __asm__ __volatile__( + ".align 8\n" + "1:\n" + "movd (%1), %%mm0\n" /* 4 Cb 0 0 0 0 u3 u2 u1 u0 */ + "pxor %%mm7, %%mm7\n" + "movd (%0), %%mm1\n" /* 4 Cr 0 0 0 0 v3 v2 v1 v0 */ + "punpcklbw %%mm7, %%mm0\n" /* 4 W cb 0 u3 0 u2 0 u1 0 u0 */ + "punpcklbw %%mm7, %%mm1\n" /* 4 W cr 0 v3 0 v2 0 v1 0 v0 */ + + "psubw mpeg3_MMX_80w, %%mm0\n" + "psubw mpeg3_MMX_80w, %%mm1\n" + "movq %%mm0, %%mm2\n" /* Cb 0 u3 0 u2 0 u1 0 u0 */ + "movq %%mm1, %%mm3\n" /* Cr */ + "pmullw mpeg3_MMX_Ugrncoeff, %%mm2\n" /* Cb2green 0 R3 0 R2 0 R1 0 R0 */ + "movq (%2), %%mm6\n" /* L1 l7 L6 L5 L4 L3 L2 L1 L0 */ + "pmullw mpeg3_MMX_Ublucoeff, %%mm0\n" /* Cb2blue */ + "pand mpeg3_MMX_00FFw, %%mm6\n" /* L1 00 L6 00 L4 00 L2 00 L0 */ + "pmullw mpeg3_MMX_Vgrncoeff, %%mm3\n" /* Cr2green */ + "movq (%2), %%mm7\n" /* L2 */ + "pmullw mpeg3_MMX_Vredcoeff, %%mm1\n" /* Cr2red */ + "psrlw $8, %%mm7\n" /* L2 00 L7 00 L5 00 L3 00 L1 */ + "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum1 */ + "paddw %%mm3, %%mm2\n" /* Cb2green + Cr2green == green */ + "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum2 */ + + "movq %%mm6, %%mm4\n" /* lum1 */ + "paddw %%mm0, %%mm6\n" /* lum1 +blue 00 B6 00 B4 00 B2 00 B0 */ + "movq %%mm4, %%mm5\n" /* lum1 */ + "paddw %%mm1, %%mm4\n" /* lum1 +red 00 R6 00 R4 00 R2 00 R0 */ + "paddw %%mm2, %%mm5\n" /* lum1 +green 00 G6 00 G4 00 G2 00 G0 */ + "psraw $6, %%mm4\n" /* R1 0 .. 64 */ + "movq %%mm7, %%mm3\n" /* lum2 00 L7 00 L5 00 L3 00 L1 */ + "psraw $6, %%mm5\n" /* G1 - .. + */ + "paddw %%mm0, %%mm7\n" /* Lum2 +blue 00 B7 00 B5 00 B3 00 B1 */ + "psraw $6, %%mm6\n" /* B1 0 .. 64 */ + "packuswb %%mm4, %%mm4\n" /* R1 R1 */ + "packuswb %%mm5, %%mm5\n" /* G1 G1 */ + "packuswb %%mm6, %%mm6\n" /* B1 B1 */ + "punpcklbw %%mm4, %%mm4\n" + "punpcklbw %%mm5, %%mm5\n" + + "pand mpeg3_MMX_redmask, %%mm4\n" + "psllw $3, %%mm5\n" /* GREEN 1 */ + "punpcklbw %%mm6, %%mm6\n" + "pand mpeg3_MMX_grnmask, %%mm5\n" + "pand mpeg3_MMX_redmask, %%mm6\n" + "por %%mm5, %%mm4\n" /* */ + "psrlw $11, %%mm6\n" /* BLUE 1 */ + "movq %%mm3, %%mm5\n" /* lum2 */ + "paddw %%mm1, %%mm3\n" /* lum2 +red 00 R7 00 R5 00 R3 00 R1 */ + "paddw %%mm2, %%mm5\n" /* lum2 +green 00 G7 00 G5 00 G3 00 G1 */ + "psraw $6, %%mm3\n" /* R2 */ + "por %%mm6, %%mm4\n" /* MM4 */ + "psraw $6, %%mm5\n" /* G2 */ + "movq (%2, %3), %%mm6\n" /* L3 */ + "psraw $6, %%mm7\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm5, %%mm5\n" + "packuswb %%mm7, %%mm7\n" + "pand mpeg3_MMX_00FFw, %%mm6\n" /* L3 */ + "punpcklbw %%mm3, %%mm3\n" + "punpcklbw %%mm5, %%mm5\n" + "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum3 */ + "punpcklbw %%mm7, %%mm7\n" + "psllw $3, %%mm5\n" /* GREEN 2 */ + "pand mpeg3_MMX_redmask, %%mm7\n" + "pand mpeg3_MMX_redmask, %%mm3\n" + "psrlw $11, %%mm7\n" /* BLUE 2 */ + "pand mpeg3_MMX_grnmask, %%mm5\n" + "por %%mm7, %%mm3\n" + "movq (%2,%3), %%mm7\n" /* L4 */ + "por %%mm5, %%mm3\n" /* */ + "psrlw $8, %%mm7\n" /* L4 */ + "movq %%mm4, %%mm5\n" + "punpcklwd %%mm3, %%mm4\n" + "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum4 */ + "punpckhwd %%mm3, %%mm5\n" + + "movq %%mm4, (%4)\n" + "movq %%mm5, 8(%4)\n" + + "movq %%mm6, %%mm4\n" /* Lum3 */ + "paddw %%mm0, %%mm6\n" /* Lum3 +blue */ + + "movq %%mm4, %%mm5\n" /* Lum3 */ + "paddw %%mm1, %%mm4\n" /* Lum3 +red */ + "paddw %%mm2, %%mm5\n" /* Lum3 +green */ + "psraw $6, %%mm4\n" + "movq %%mm7, %%mm3\n" /* Lum4 */ + "psraw $6, %%mm5\n" + "paddw %%mm0, %%mm7\n" /* Lum4 +blue */ + "psraw $6, %%mm6\n" /* Lum3 +blue */ + "movq %%mm3, %%mm0\n" /* Lum4 */ + "packuswb %%mm4, %%mm4\n" + "paddw %%mm1, %%mm3\n" /* Lum4 +red */ + "packuswb %%mm5, %%mm5\n" + "paddw %%mm2, %%mm0\n" /* Lum4 +green */ + "packuswb %%mm6, %%mm6\n" + "punpcklbw %%mm4, %%mm4\n" + "punpcklbw %%mm5, %%mm5\n" + "punpcklbw %%mm6, %%mm6\n" + "psllw $3, %%mm5\n" /* GREEN 3 */ + "pand mpeg3_MMX_redmask, %%mm4\n" + "psraw $6, %%mm3\n" /* psr 6 */ + "psraw $6, %%mm0\n" + "pand mpeg3_MMX_redmask, %%mm6\n" /* BLUE */ + "pand mpeg3_MMX_grnmask, %%mm5\n" + "psrlw $11, %%mm6\n" /* BLUE 3 */ + "por %%mm5, %%mm4\n" + "psraw $6, %%mm7\n" + "por %%mm6, %%mm4\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm0, %%mm0\n" + "packuswb %%mm7, %%mm7\n" + "punpcklbw %%mm3, %%mm3\n" + "punpcklbw %%mm0, %%mm0\n" + "punpcklbw %%mm7, %%mm7\n" + "pand mpeg3_MMX_redmask, %%mm3\n" + "pand mpeg3_MMX_redmask, %%mm7\n" /* BLUE */ + "psllw $3, %%mm0\n" /* GREEN 4 */ + "psrlw $11, %%mm7\n" + "pand mpeg3_MMX_grnmask, %%mm0\n" + "por %%mm7, %%mm3\n" + "addl $8, %6\n" + "por %%mm0, %%mm3\n" + + "movq %%mm4, %%mm5\n" + + "punpcklwd %%mm3, %%mm4\n" + "punpckhwd %%mm3, %%mm5\n" + + "movq %%mm4, (%4,%5,2)\n" + "movq %%mm5, 8(%4,%5,2)\n" + + "addl $8, %2\n" + "addl $4, %0\n" + "addl $4, %1\n" + "cmpl %3, %6\n" + "leal 16(%4), %4\n" + "jl 1b\n" + "addl %3, %2\n" /* lum += cols */ + "addl %7, %4\n" /* row1 += mod */ + "movl $0, %6\n" + "cmpl %8, %2\n" + "jl 1b\n" + : : "r" (cr), + "r" (cb), + "r" (lum), + "r" (cols), + "r" (row1) , + "r" (col1), + "m" (x), + "m" (mod), + "m" (y) + ); +} + +static unsigned LONGLONG mpeg3_MMX_U_80 = 0x0000008000800000LL; +static unsigned LONGLONG mpeg3_MMX_V_80 = 0x0000000000800080LL; +static LONGLONG mpeg3_MMX_U_COEF = 0x00000058ffd30000LL; +static LONGLONG mpeg3_MMX_V_COEF = 0x00000000ffea006fLL; +static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004800480048LL; +static LONGLONG mpeg3_MMX_601_Y_DIFF = 0x0000000000000010LL; + +inline void mpeg3_bgra32_mmx(unsigned long y, + unsigned long u, + unsigned long v, + unsigned long *output) +{ +asm(" +/* Output will be 0x00rrggbb with the 00 trailing so this can also be used */ +/* for bgr24. */ + movd (%0), %%mm0; /* Load y 0x00000000000000yy */ + movd (%1), %%mm1; /* Load u 0x00000000000000cr */ + movq %%mm0, %%mm3; /* Copy y to temp */ + psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */ + movd (%2), %%mm2; /* Load v 0x00000000000000cb */ + psllq $16, %%mm3; /* Shift y */ + movq %%mm1, %%mm4; /* Copy u to temp */ + por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */ + psllq $16, %%mm4; /* Shift u */ + movq %%mm2, %%mm5; /* Copy v to temp */ + psllq $16, %%mm3; /* Shift y */ + por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */ + psllq $16, %%mm5; /* Shift v */ + por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */ + por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */ + +/* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */ + psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */ + pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */ + psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */ + psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */ + pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */ + +/* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */ + paddsw %%mm1, %%mm0; /* Add u to result */ + paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */ + psraw $6, %%mm0; /* Demote precision */ + packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */ + movd %%mm0, (%3); /* Store output */ + " +: +: "r" (&y), "r" (&u), "r" (&v), "r" (output)); +} + +inline void mpeg3_601_bgra32_mmx(unsigned long y, + unsigned long u, + unsigned long v, + unsigned long *output) +{ +asm(" +/* Output will be 0x00rrggbb with the 00 trailing so this can also be used */ +/* for bgr24. */ + movd (%0), %%mm0; /* Load y 0x00000000000000yy */ + psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */ + movd (%1), %%mm1; /* Load u 0x00000000000000cr */ + movq %%mm0, %%mm3; /* Copy y to temp */ + psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */ + movd (%2), %%mm2; /* Load v 0x00000000000000cb */ + psllq $16, %%mm3; /* Shift y */ + movq %%mm1, %%mm4; /* Copy u to temp */ + por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */ + psllq $16, %%mm4; /* Shift u */ + movq %%mm2, %%mm5; /* Copy v to temp */ + psllq $16, %%mm3; /* Shift y */ + por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */ + psllq $16, %%mm5; /* Shift v */ + por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */ + por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */ + +/* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */ + pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale and shift y coeffs */ + psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */ + pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */ + psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */ + pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */ + +/* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */ + paddsw %%mm1, %%mm0; /* Add u to result */ + paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */ + psraw $6, %%mm0; /* Demote precision */ + packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */ + movd %%mm0, (%3); /* Store output */ + " +: +: "r" (&y), "r" (&u), "r" (&v), "r" (output)); +} + +static unsigned LONGLONG mpeg3_MMX_U_80_RGB = 0x0000000000800080LL; +static unsigned LONGLONG mpeg3_MMX_V_80_RGB = 0x0000008000800000LL; +static LONGLONG mpeg3_MMX_U_COEF_RGB = 0x00000000ffd30058LL; +static LONGLONG mpeg3_MMX_V_COEF_RGB = 0x0000006fffea0000LL; + +inline void mpeg3_rgba32_mmx(unsigned long y, + unsigned long u, + unsigned long v, + unsigned long *output) +{ +asm(" +/* Output will be 0x00bbggrr with the 00 trailing so this can also be used */ +/* for rgb24. */ + movd (%0), %%mm0; /* Load y 0x00000000000000yy */ + movd (%1), %%mm1; /* Load v 0x00000000000000vv */ + movq %%mm0, %%mm3; /* Copy y to temp */ + psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */ + movd (%2), %%mm2; /* Load u 0x00000000000000uu */ + psllq $16, %%mm3; /* Shift y */ + movq %%mm1, %%mm4; /* Copy v to temp */ + por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */ + psllq $16, %%mm4; /* Shift v */ + movq %%mm2, %%mm5; /* Copy u to temp */ + psllq $16, %%mm3; /* Shift y */ + por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */ + psllq $16, %%mm5; /* Shift u */ + por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */ + por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */ + +/* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */ + psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */ + pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */ + psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */ + psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */ + pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */ + +/* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */ + paddsw %%mm1, %%mm0; /* Add v to result */ + paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */ + psraw $6, %%mm0; /* Demote precision */ + packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */ + movd %%mm0, (%3); /* Store output */ + " +: +: "r" (&y), "r" (&v), "r" (&u), "r" (output)); +} + +inline void mpeg3_601_rgba32_mmx(unsigned long y, + unsigned long u, + unsigned long v, + unsigned long *output) +{ +asm(" +/* Output will be 0x00bbggrr with the 00 trailing so this can also be used */ +/* for rgb24. */ + movd (%0), %%mm0; /* Load y 0x00000000000000yy */ + psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */ + movd (%1), %%mm1; /* Load v 0x00000000000000vv */ + movq %%mm0, %%mm3; /* Copy y to temp */ + psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */ + movd (%2), %%mm2; /* Load u 0x00000000000000uu */ + psllq $16, %%mm3; /* Shift y */ + movq %%mm1, %%mm4; /* Copy v to temp */ + por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */ + psllq $16, %%mm4; /* Shift v */ + movq %%mm2, %%mm5; /* Copy u to temp */ + psllq $16, %%mm3; /* Shift y */ + por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */ + psllq $16, %%mm5; /* Shift u */ + por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */ + por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */ + +/* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */ + pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale y coeffs */ + psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */ + pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */ + psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */ + pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */ + +/* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */ + paddsw %%mm1, %%mm0; /* Add v to result */ + paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */ + psraw $6, %%mm0; /* Demote precision */ + packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */ + movd %%mm0, (%3); /* Store output */ + " +: +: "r" (&y), "r" (&v), "r" (&u), "r" (output)); +} + +#endif + +#define DITHER_ROW_HEAD \ + for(h = 0; h < video->out_h; h++) \ + { \ + y_in = &src[0][(video->y_table[h] + video->in_y) * video->coded_picture_width] + video->in_x; \ + cb_in = &src[1][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 2); \ + cr_in = &src[2][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 1); \ + data = output_rows[h]; + +#define DITHER_ROW_TAIL \ + } + +#define DITHER_SCALE_HEAD \ + for(w = 0; w < video->out_w; w++) \ + { \ + uv_subscript = video->x_table[w] / 2; \ + y_l = y_in[video->x_table[w]]; \ + y_l <<= 16; \ + r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \ + g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \ + b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16; + +#define DITHER_SCALE_601_HEAD \ + for(w = 0; w < video->out_w; w++) \ + { \ + uv_subscript = video->x_table[w] / 2; \ + y_l = mpeg3_601_to_rgb[y_in[video->x_table[w]]]; \ + y_l <<= 16; \ + r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \ + g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \ + b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16; + +#define DITHER_SCALE_TAIL \ + } + +#define DITHER_MMX_SCALE_HEAD \ + for(w = 0; w < video->out_w; w++) \ + { \ + uv_subscript = video->x_table[w] / 2; + +#define DITHER_MMX_SCALE_TAIL \ + data += step; \ + } + +#define DITHER_MMX_HEAD \ + for(w = 0; w < video->out_w; w += 2) \ + { + +#define DITHER_MMX_TAIL \ + data += step; \ + cr_in++; \ + cb_in++; \ + } + +#define DITHER_HEAD \ + for(w = 0; w < video->horizontal_size; w++) \ + { \ + y_l = *y_in++; \ + y_l <<= 16; \ + r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \ + g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \ + b_l = (y_l + video->cb_to_b[*cb_in]) >> 16; + +#define DITHER_601_HEAD \ + for(w = 0; w < video->horizontal_size; w++) \ + { \ + y_l = mpeg3_601_to_rgb[*y_in++]; \ + y_l <<= 16; \ + r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \ + g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \ + b_l = (y_l + video->cb_to_b[*cb_in]) >> 16; + +#define DITHER_TAIL \ + if(w & 1) \ + { \ + cr_in++; \ + cb_in++; \ + } \ + } + + +#define STORE_PIXEL_BGR888 \ + *data++ = CLIP(b_l); \ + *data++ = CLIP(g_l); \ + *data++ = CLIP(r_l); + +#define STORE_PIXEL_BGRA8888 \ + *data++ = CLIP(b_l); \ + *data++ = CLIP(g_l); \ + *data++ = CLIP(r_l); \ + *data++ = 0; + +#define STORE_PIXEL_RGB565 \ + *((unsigned short*)data)++ = \ + ((CLIP(r_l) & 0xf8) << 8) | \ + ((CLIP(g_l) & 0xfc) << 3) | \ + ((CLIP(b_l) & 0xf8) >> 3); + +#define STORE_PIXEL_RGB888 \ + *data++ = CLIP(r_l); \ + *data++ = CLIP(g_l); \ + *data++ = CLIP(b_l); + +#define STORE_PIXEL_RGBA8888 \ + *data++ = CLIP(r_l); \ + *data++ = CLIP(g_l); \ + *data++ = CLIP(b_l); \ + *data++ = 0; + +#define STORE_PIXEL_RGBA16161616 \ + *data_s++ = CLIP(r_l); \ + *data_s++ = CLIP(g_l); \ + *data_s++ = CLIP(b_l); \ + *data_s++ = 0; + + + +/* Only good for YUV 4:2:0 */ +int mpeg3video_ditherframe(mpeg3video_t *video, unsigned char **src, unsigned char **output_rows) +{ + int h = 0; + register unsigned char *y_in, *cb_in, *cr_in; + long y_l, r_l, b_l, g_l; + register unsigned char *data; + register int uv_subscript, step, w = -1; + +#ifdef HAVE_MMX +/* =================================== MMX ===================================== */ + if(video->have_mmx && + video->out_w == video->horizontal_size && + video->out_h == video->vertical_size && + video->in_w == video->out_w && + video->in_h == video->out_h && + video->in_x == 0 && + video->in_y == 0 && + (video->color_model == MPEG3_RGB565 || video->color_model == MPEG3_601_RGB565)) + { +/* Unscaled 16 bit */ + mpeg3video_rgb16_mmx(src[0], + src[2], + src[1], + output_rows[0], + video->out_h, + video->out_w, + (output_rows[1] - output_rows[0]) / 2 - video->out_w); + } + else + if(video->have_mmx && + (video->color_model == MPEG3_BGRA8888 || + video->color_model == MPEG3_BGR888 || +/* video->color_model == MPEG3_RGB888 || */ + video->color_model == MPEG3_RGBA8888 || + video->color_model == MPEG3_601_BGR888 || + video->color_model == MPEG3_601_BGRA8888 || + video->color_model == MPEG3_601_RGB888 || + video->color_model == MPEG3_601_RGBA8888)) + { +/* Original MMX */ + if(video->color_model == MPEG3_BGRA8888 || + video->color_model == MPEG3_RGBA8888 || + video->color_model == MPEG3_601_BGRA8888 || + video->color_model == MPEG3_601_RGBA8888) step = 4; + else + if(video->color_model == MPEG3_BGR888 || + video->color_model == MPEG3_RGB888 || + video->color_model == MPEG3_601_BGR888 || + video->color_model == MPEG3_601_RGB888) step = 3; + + DITHER_ROW_HEAD +/* Transfer row with scaling */ + if(video->out_w != video->horizontal_size) + { + switch(video->color_model) + { + case MPEG3_BGRA8888: + case MPEG3_BGR888: + DITHER_MMX_SCALE_HEAD + mpeg3_bgra32_mmx(y_in[video->x_table[w]], + cr_in[uv_subscript], + cb_in[uv_subscript], + (unsigned long*)data); + DITHER_MMX_SCALE_TAIL + break; + + case MPEG3_601_BGRA8888: + case MPEG3_601_BGR888: + DITHER_MMX_SCALE_HEAD + mpeg3_601_bgra32_mmx(y_in[video->x_table[w]], + cr_in[uv_subscript], + cb_in[uv_subscript], + (unsigned long*)data); + DITHER_MMX_SCALE_TAIL + break; + + case MPEG3_RGBA8888: + case MPEG3_RGB888: + DITHER_MMX_SCALE_HEAD + mpeg3_rgba32_mmx(y_in[video->x_table[w]], + cr_in[uv_subscript], + cb_in[uv_subscript], + (unsigned long*)data); + DITHER_MMX_SCALE_TAIL + break; + + case MPEG3_601_RGBA8888: + case MPEG3_601_RGB888: + DITHER_MMX_SCALE_HEAD + mpeg3_601_rgba32_mmx(y_in[video->x_table[w]], + cr_in[uv_subscript], + cb_in[uv_subscript], + (unsigned long*)data); + DITHER_MMX_SCALE_TAIL + break; + } + } + else +/* Transfer row unscaled */ + { + switch(video->color_model) + { +/* MMX byte swap 24 and 32 bit */ + case MPEG3_BGRA8888: + case MPEG3_BGR888: + DITHER_MMX_HEAD + mpeg3_bgra32_mmx(*y_in++, + *cr_in, + *cb_in, + (unsigned long*)data); + data += step; + mpeg3_bgra32_mmx(*y_in++, + *cr_in, + *cb_in, + (unsigned long*)data); + DITHER_MMX_TAIL + break; + +/* MMX 601 byte swap 24 and 32 bit */ + case MPEG3_601_BGRA8888: + case MPEG3_601_BGR888: + DITHER_MMX_HEAD + mpeg3_601_bgra32_mmx(*y_in++, + *cr_in, + *cb_in, + (unsigned long*)data); + data += step; + mpeg3_601_bgra32_mmx(*y_in++, + *cr_in, + *cb_in, + (unsigned long*)data); + DITHER_MMX_TAIL + break; + +/* MMX 24 and 32 bit no byte swap */ + case MPEG3_RGBA8888: + case MPEG3_RGB888: + DITHER_MMX_HEAD + mpeg3_rgba32_mmx(*y_in++, + *cr_in, + *cb_in, + (unsigned long*)data); + data += step; + mpeg3_rgba32_mmx(*y_in++, + *cr_in, + *cb_in, + (unsigned long*)data); + DITHER_MMX_TAIL + break; + +/* MMX 601 24 and 32 bit no byte swap */ + case MPEG3_601_RGBA8888: + case MPEG3_601_RGB888: + DITHER_MMX_HEAD + mpeg3_601_rgba32_mmx(*y_in++, + *cr_in, + *cb_in, + (unsigned long*)data); + data += step; + mpeg3_601_rgba32_mmx(*y_in++, + *cr_in, + *cb_in, + (unsigned long*)data); + DITHER_MMX_TAIL + break; + } + } + DITHER_ROW_TAIL + } + else +#endif +/* ================================== NO MMX ==================================== */ + { + DITHER_ROW_HEAD +/* Transfer row with scaling */ + if(video->out_w != video->horizontal_size) + { + switch(video->color_model) + { + case MPEG3_BGR888: + DITHER_SCALE_HEAD + STORE_PIXEL_BGR888 + DITHER_SCALE_TAIL + break; + case MPEG3_BGRA8888: + DITHER_SCALE_HEAD + STORE_PIXEL_BGRA8888 + DITHER_SCALE_TAIL + break; + case MPEG3_RGB565: + DITHER_SCALE_HEAD + STORE_PIXEL_RGB565 + DITHER_SCALE_TAIL + break; + case MPEG3_RGB888: + DITHER_SCALE_HEAD + STORE_PIXEL_RGB888 + DITHER_SCALE_TAIL + break; + case MPEG3_RGBA8888: + DITHER_SCALE_HEAD + STORE_PIXEL_RGBA8888 + DITHER_SCALE_TAIL + break; + case MPEG3_601_BGR888: + DITHER_SCALE_601_HEAD + STORE_PIXEL_BGR888 + DITHER_SCALE_TAIL + break; + case MPEG3_601_BGRA8888: + DITHER_SCALE_601_HEAD + STORE_PIXEL_BGRA8888 + DITHER_SCALE_TAIL + break; + case MPEG3_601_RGB565: + DITHER_SCALE_601_HEAD + STORE_PIXEL_RGB565 + DITHER_SCALE_TAIL + break; + case MPEG3_601_RGB888: + DITHER_SCALE_601_HEAD + STORE_PIXEL_RGB888 + DITHER_SCALE_TAIL + break; + case MPEG3_601_RGBA8888: + DITHER_SCALE_601_HEAD + STORE_PIXEL_RGBA8888 + DITHER_SCALE_TAIL + break; + case MPEG3_RGBA16161616: + { + register unsigned short *data_s = (unsigned short*)data; + DITHER_SCALE_HEAD + STORE_PIXEL_RGBA16161616 + DITHER_SCALE_TAIL + } + break; + } + } + else + { +/* Transfer row unscaled */ + switch(video->color_model) + { + case MPEG3_BGR888: + DITHER_HEAD + STORE_PIXEL_BGR888 + DITHER_TAIL + break; + case MPEG3_BGRA8888: + DITHER_HEAD + STORE_PIXEL_BGRA8888 + DITHER_TAIL + break; + case MPEG3_RGB565: + DITHER_HEAD + STORE_PIXEL_RGB565 + DITHER_TAIL + break; + case MPEG3_RGB888: + DITHER_HEAD + STORE_PIXEL_RGB888 + DITHER_TAIL + break; + case MPEG3_RGBA8888: + DITHER_HEAD + STORE_PIXEL_RGBA8888 + DITHER_TAIL + break; + case MPEG3_601_BGR888: + DITHER_601_HEAD + STORE_PIXEL_BGR888 + DITHER_TAIL + break; + case MPEG3_601_BGRA8888: + DITHER_601_HEAD + STORE_PIXEL_RGB565 + DITHER_TAIL + break; + case MPEG3_601_RGB565: + DITHER_601_HEAD + STORE_PIXEL_RGB565 + DITHER_TAIL + break; + case MPEG3_601_RGB888: + DITHER_601_HEAD + STORE_PIXEL_RGB888 + DITHER_TAIL + break; + case MPEG3_601_RGBA8888: + DITHER_601_HEAD + STORE_PIXEL_RGBA8888 + DITHER_TAIL + break; + case MPEG3_RGBA16161616: + { + register unsigned short *data_s = (unsigned short*)data; + DITHER_HEAD + STORE_PIXEL_RGBA16161616 + DITHER_TAIL + } + break; + } + } + DITHER_ROW_TAIL + } /* End of non-MMX */ + +#ifdef HAVE_MMX + if(video->have_mmx) + __asm__ __volatile__ ("emms"); +#endif + return 0; +} + +int mpeg3video_ditherframe444(mpeg3video_t *video, unsigned char *src[]) +{ + return 0; +} + +int mpeg3video_dithertop(mpeg3video_t *video, unsigned char *src[]) +{ + return mpeg3video_ditherframe(video, src, video->output_rows); +} + +int mpeg3video_dithertop444(mpeg3video_t *video, unsigned char *src[]) +{ + return 0; +} + +int mpeg3video_ditherbot(mpeg3video_t *video, unsigned char *src[]) +{ + return 0; +} + +int mpeg3video_ditherbot444(mpeg3video_t *video, unsigned char *src[]) +{ + return 0; +} + +void memcpy_fast(unsigned char *output, unsigned char *input, long len) +{ + int i, len2; +/* 8 byte alignment */ +/* + * if(!((long)input & 0x7)) + * { + * len2 = len >> 4; + * for(i = 0; i < len2; ) + * { + * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i]; + * i++; + * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i]; + * i++; + * } + * + * for(i *= 16; i < len; i++) + * { + * output[i] = input[i]; + * } + * } + * else + */ + memcpy(output, input, len); +} + +int mpeg3video_init_output() +{ + int i, value; + for(i = 0; i < 256; i++) + { + value = (int)(1.1644 * i - 255 * 0.0627 + 0.5); + if(value < 0) value = 0; + else + if(value > 255) value = 255; + mpeg3_601_to_rgb[i] = value; + } + return 0; +} + +int mpeg3video_present_frame(mpeg3video_t *video) +{ + int i, j, k, l; + unsigned char **src = video->output_src; + +/* Copy YUV buffers */ + if(video->want_yvu) + { + long size[2]; + long offset[2]; + +/* Drop a frame */ + if(!video->y_output) return 0; + +/* Copy a frame */ + if(video->in_x == 0 && + video->in_w >= video->coded_picture_width) + { + size[0] = video->coded_picture_width * video->in_h; + size[1] = video->chrom_width * (int)((float)video->in_h / 2 + 0.5); + offset[0] = video->coded_picture_width * video->in_y; + offset[1] = video->chrom_width * (int)((float)video->in_y / 2 + 0.5); + +/* + * if(video->in_y > 0) + * { + * offset[1] += video->chrom_width / 2; + * size[1] += video->chrom_width / 2; + * } + */ + + memcpy(video->y_output, src[0] + offset[0], size[0]); + memcpy(video->u_output, src[1] + offset[1], size[1]); + memcpy(video->v_output, src[2] + offset[1], size[1]); + } + else + { + for(i = 0, j = video->in_y; i < video->in_h; i++, j++) + { + memcpy(video->y_output + i * video->in_w, + src[0] + j * video->coded_picture_width + video->in_x, + video->in_w); + memcpy(video->u_output + i * video->in_w / 4, + src[1] + j * video->chrom_width / 2 + video->in_x / 4, + video->in_w / 4); + memcpy(video->v_output + i * video->in_w / 4, + src[2] + j * video->chrom_width / 2 + video->in_x / 4, + video->in_w / 4); + } + } + + return 0; + } + +/* Want RGB buffer */ +/* Copy the frame to the output with YUV to RGB conversion */ + if(video->prog_seq) + { + if(video->chroma_format != CHROMA444) + { + mpeg3video_ditherframe(video, src, video->output_rows); + } + else + mpeg3video_ditherframe444(video, src); + } + else + { + if((video->pict_struct == FRAME_PICTURE && video->topfirst) || + video->pict_struct == BOTTOM_FIELD) + { +/* top field first */ + if(video->chroma_format != CHROMA444) + { + mpeg3video_dithertop(video, src); + mpeg3video_ditherbot(video, src); + } + else + { + mpeg3video_dithertop444(video, src); + mpeg3video_ditherbot444(video, src); + } + } + else + { +/* bottom field first */ + if(video->chroma_format != CHROMA444) + { + mpeg3video_ditherbot(video, src); + mpeg3video_dithertop(video, src); + } + else + { + mpeg3video_ditherbot444(video, src); + mpeg3video_dithertop444(video, src); + } + } + } + return 0; +} + +int mpeg3video_display_second_field(mpeg3video_t *video) +{ +/* Not used */ + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/reconmmx.s b/core/multimedia/opieplayer/libmpeg3/video/reconmmx.s new file mode 100644 index 0000000..1bb98ef --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/reconmmx.s @@ -0,0 +1,301 @@ +ADD_1: dd 01010101h, 01010101h +MASK_AND: dd 7f7f7f7fh, 7f7f7f7fh +PLUS_384: dd 01800180h, 01800180h +PLUS_128: dd 00800080h, 00800080h + +%assign LocalFrameSize 0 +%assign RegisterStorageSize 16 + +; Arguments: +%assign source LocalFrameSize + RegisterStorageSize + 4 +%assign dest LocalFrameSize + RegisterStorageSize + 8 +%assign lx2 LocalFrameSize + RegisterStorageSize + 12 +%assign h LocalFrameSize + RegisterStorageSize + 16 + +; Locals (on local stack frame) + + +; extern void C rec_mmx ( +; unsigned char *source, +; unsigned char *dest, +; int lx2, +; int h +; +; The local variables are on the stack, +; + +global recva_mmx +global recvac_mmx +global rech_mmx +global rechc_mmx +global add_block_mmx +global set_block_mmx + + + align 16 +rech_mmx: + push esi + push edi + push ecx + push ebx + mov esi, [esp+source] + mov edi, [esp+dest] + mov ecx, [esp+h] + mov ebx, [esp+lx2] + movq mm5, [MASK_AND] + movq mm6, [ADD_1] +.rech1: + movq mm0,[esi] + movq mm1,[esi+1] + movq mm2,[esi+8] + movq mm3,[esi+9] + psrlw mm0,1 + psrlw mm1,1 + psrlw mm2,1 + psrlw mm3,1 + pand mm0,mm5 + pand mm1,mm5 + pand mm2,mm5 + pand mm3,mm5 + paddusb mm0,mm1 + paddusb mm2,mm3 + paddusb mm0,mm6 + paddusb mm2,mm6 + movq [edi],mm0 + add esi,ebx + movq [edi+8],mm2 + add edi,ebx + dec ecx + jnz .rech1 + emms + pop ebx + pop ecx + pop edi + pop esi + ret + + align 16 +rechc_mmx: + push esi + push edi + push ecx + push ebx +; sub esp, LocalFrameSize + mov esi, [esp+source] + mov edi, [esp+dest] + mov ecx, [esp+h] + mov ebx, [esp+lx2] + movq mm5, [MASK_AND] + movq mm6, [ADD_1] +.rechc1: + movq mm0,[esi] + movq mm1,[esi+1] + psrlw mm0,1 + psrlw mm1,1 + pand mm0,mm5 + pand mm1,mm5 + paddusb mm0,mm1 + paddusb mm0,mm6 + movq [edi],mm0 + add edi,ebx + add esi,ebx + dec ecx + jnz .rechc1 + emms +; add esp, LocalFrameSize + pop ebx + pop ecx + pop edi + pop esi + ret + + + +%assign RegisterStorageSize 20 +%assign source LocalFrameSize + RegisterStorageSize + 4 +%assign dest LocalFrameSize + RegisterStorageSize + 8 +%assign lx LocalFrameSize + RegisterStorageSize + 12 +%assign lx2 LocalFrameSize + RegisterStorageSize + 16 +%assign h LocalFrameSize + RegisterStorageSize + 20 + + align 16 +recva_mmx: + push esi + push edi + push ecx + push ebx + push edx + mov esi, [esp+source] + mov edi, [esp+dest] + mov ecx, [esp+h] + mov ebx, [esp+lx2] + mov edx, [esp+lx] + movq mm7, [MASK_AND] + movq mm6, [ADD_1] +.recva1: + movq mm0,[esi] + movq mm1,[esi+edx] + movq mm2,[esi+8] + movq mm3,[esi+edx+8] + movq mm4,[edi] + movq mm5,[edi+8] + psrlw mm0,1 + psrlw mm1,1 + psrlw mm2,1 + psrlw mm3,1 + psrlw mm4,1 + psrlw mm5,1 + pand mm0,mm7 + pand mm1,mm7 + pand mm2,mm7 + pand mm3,mm7 + pand mm4,mm7 + pand mm5,mm7 + paddusb mm0,mm1 + paddusb mm2,mm3 + paddusb mm0,mm6 + paddusb mm2,mm6 + psrlw mm0,1 + psrlw mm2,1 + pand mm0,mm7 + pand mm2,mm7 + paddusb mm4,mm0 + paddusb mm5,mm2 + paddusb mm4,mm6 + paddusb mm5,mm6 + movq [edi],mm4 + movq [edi+8],mm5 + add edi,ebx + add esi,ebx + dec ecx + jnz near .recva1 + emms + pop edx + pop ebx + pop ecx + pop edi + pop esi + ret + + align 16 +recvac_mmx: + push esi + push edi + push ecx + push ebx + push edx + mov esi, [esp+source] + mov edi, [esp+dest] + mov ecx, [esp+h] + mov ebx, [esp+lx2] + mov edx, [esp+lx] + movq mm5, [MASK_AND] + movq mm6, [ADD_1] +.recvac1: + movq mm0,[esi] + movq mm1,[esi+edx] + movq mm4,[edi] + psrlw mm0,1 + psrlw mm1,1 + psrlw mm4,1 + pand mm0,mm5 + pand mm1,mm5 + pand mm4,mm5 + paddusb mm0,mm1 + paddusb mm0,mm6 + psrlw mm0,1 + pand mm0,mm5 + paddusb mm4,mm0 + paddusb mm4,mm6 + movq [edi],mm4 + add edi,ebx + add esi,ebx + dec ecx + jnz .recvac1 + emms + pop edx + pop ebx + pop ecx + pop edi + pop esi + ret + +%assign RegisterStorageSize 20 +%assign rfp LocalFrameSize + RegisterStorageSize + 4 +%assign bp LocalFrameSize + RegisterStorageSize + 8 +%assign iincr LocalFrameSize + RegisterStorageSize + 12 + +; FIXME clipping needs to be done + + align 16 +add_block_mmx: + push esi + push edi + push ecx + push ebx + push edx + mov esi, [esp+bp] + mov edi, [esp+rfp] + mov ebx, [esp+iincr] +; movq mm7, [PLUS_384] + mov ecx,8 + pxor mm2,mm2 ; clear +%rep 8 + movq mm0, [edi] ; get dest + movq mm1,mm0 + punpcklbw mm0,mm2 + punpckhbw mm1,mm2 + paddsw mm0, [esi] + paddsw mm1, [esi+8] +; paddsw mm0, mm7 +; paddsw mm1, mm7 + packuswb mm0,mm1 + movq [edi], mm0 + add edi,ebx + add esi,16 +%endrep + emms + pop edx + pop ebx + pop ecx + pop edi + pop esi + ret + + align 16 +set_block_mmx: + push esi + push edi + push ecx + push ebx + push edx + mov esi, [esp+bp] + mov edi, [esp+rfp] + mov ebx, [esp+iincr] + movq mm7, [PLUS_128] +%rep 4 + movq mm0, [esi] + movq mm1, [esi+8] + paddsw mm0, mm7 + movq mm2, [esi+16] + paddsw mm1, mm7 + movq mm3, [esi+24] + paddsw mm2, mm7 + packuswb mm0, mm1 + paddsw mm3, mm7 + movq [edi], mm0 + packuswb mm2, mm3 + add edi, ebx + add esi, 32 + movq [edi], mm2 + add edi, ebx +%endrep + emms + pop edx + pop ebx + pop ecx + pop edi + pop esi + ret + + diff --git a/core/multimedia/opieplayer/libmpeg3/video/reconstruct.c b/core/multimedia/opieplayer/libmpeg3/video/reconstruct.c new file mode 100644 index 0000000..531f9c0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/reconstruct.c @@ -0,0 +1,1290 @@ +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "mpeg3video.h" +#include + +#ifdef HAVE_MMX + +#ifdef HAVE_3Dnow +static inline void recva_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ + __asm__( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq 8(%1), %%mm1\n" /* 8 s */ + "movq (%4), %%mm2\n" /* 8 s +lx */ + "movq 8(%4), %%mm3\n" /* 8 s +lx **/ + + "pavgusb %%mm2, %%mm0\n" + "addl %3, %1\n" + "pavgusb %%mm3, %%mm1\n" + + "movq (%2), %%mm2\n" /* 8 d */ + "movq 8(%2), %%mm3\n" /* 8 d */ + "pavgusb %%mm2, %%mm0\n" + "addl %3, %4\n" + "pavgusb %%mm3, %%mm1\n" + + "movq %%mm0, (%2)\n" + "movq %%mm1, 8(%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +} + +static inline void recvac_mmx(unsigned char *s, unsigned char *d, int lx,int lx2, int h) +{ + __asm__( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq (%4), %%mm2\n" /* 8 s +lx */ + "addl %3, %1\n" + "pavgusb %%mm2, %%mm0\n" + "movq (%2), %%mm3\n" /* 8 d */ + "addl %3, %4\n" + "pavgusb %%mm3, %%mm0\n" + "movq %%mm0, (%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +} + +static inline void rech_mmx(unsigned char *s, unsigned char *d, int lx2, int h) +{ + __asm__ ( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq 8(%1), %%mm1\n" /* 8 s */ + "movq 1(%1), %%mm2\n" /* 8 s */ + "movq 9(%1), %%mm3\n" /* 8 s */ + + "pavgusb %%mm2, %%mm0\n" + "addl %3, %1\n" + "pavgusb %%mm3, %%mm1\n" + + "movq %%mm0, (%2)\n" + "movq %%mm1, 8(%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +} + +static inline void rechc_mmx(unsigned char *s, unsigned char *d, int lx2, int h) +{ + __asm__ ( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq 1(%1), %%mm2\n" /* 8 s +1 */ + "addl %3, %1\n" + "pavgusb %%mm2, %%mm0\n" + "movq %%mm0, (%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +} + +static inline void recha_mmx(unsigned char *s, unsigned char *d,int lx2, int h) +{ + __asm__ ( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq 8(%1), %%mm1\n" /* 8 s */ + "movq 1(%1), %%mm2\n" /* 8 s */ + "movq 9(%1), %%mm3\n" /* 8 s */ + + "pavgusb %%mm2, %%mm0\n" + "addl %3, %1\n" + "pavgusb %%mm3, %%mm1\n" + + "movq (%2), %%mm2\n" /* 8 d */ + "movq 8(%2), %%mm3\n" /* 8 d */ + "pavgusb %%mm2, %%mm0\n" + "pavgusb %%mm3, %%mm1\n" + + "movq %%mm0, (%2)\n" + "movq %%mm1, 8(%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +} + +static inline void rechac_mmx(unsigned char *s,unsigned char *d, int lx2, int h) +{ + __asm__ ( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq 1(%1), %%mm2\n" /* 8 s */ + + "addl %3, %1\n" + "pavgusb %%mm2, %%mm0\n" + + "movq (%2), %%mm1\n" /* 8 d */ + "pavgusb %%mm1, %%mm0\n" + + "movq %%mm0, (%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +} + +static inline void rec4_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ + __asm__ __volatile__( + "movq (%1), %%mm0\n" /* 8 s */ + "movq 8(%1), %%mm1\n" /* 8 s */ + "movq 1(%1), %%mm2\n" /* 8 s +1*/ + "movq 9(%1), %%mm3\n" /* 8 s +1*/ + ".align 8\n" + "1:" + "movq (%4), %%mm4\n" /* 8 s+lx */ + "pavgusb %%mm2, %%mm0\n" + "movq 8(%4), %%mm5\n" /* 8 s+lx */ + "pavgusb %%mm3, %%mm1\n" + + "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/ + "pavgusb %%mm4, %%mm0\n" + "movq 9(%4), %%mm7\n" /* 8 s+lx +1*/ + "pavgusb %%mm5, %%mm1\n" + + "pavgusb %%mm6, %%mm0\n" + "addl %3, %4\n" + "pavgusb %%mm7, %%mm1\n" + "movq %%mm0, (%2)\n" + "movq %%mm6, %%mm2\n" + "movq %%mm7, %%mm3\n" + "movq %%mm1, 8(%2)\n" + "movq %%mm4, %%mm0\n" + "movq %%mm5, %%mm1\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +} + +static inline void rec4c_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ + __asm__ __volatile__( + "movq (%1), %%mm0\n" /* 8 s */ + "movq 1(%1), %%mm2\n" /* 8 s +1*/ + ".align 8\n" + "1:" + "movq (%4), %%mm4\n" /* 8 s+lx */ + "pavgusb %%mm2, %%mm0\n" + + "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/ + "pavgusb %%mm4, %%mm0\n" + + "addl %3, %4\n" + "pavgusb %%mm6, %%mm0\n" + "movq %%mm0, (%2)\n" + "movq %%mm6, %%mm2\n" + "movq %%mm4, %%mm0\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +} + +static inline void rec4a_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ + __asm__ __volatile__( + "movq (%1), %%mm0\n" /* 8 s */ + "movq 8(%1), %%mm1\n" /* 8 s */ + "movq 1(%1), %%mm2\n" /* 8 s +1*/ + "movq 9(%1), %%mm3\n" /* 8 s +1*/ + ".align 8\n" + "1:" + "movq (%4), %%mm4\n" /* 8 s+lx */ + "pavgusb %%mm2, %%mm0\n" + "movq 8(%4), %%mm5\n" /* 8 s+lx */ + "pavgusb %%mm3, %%mm1\n" + + "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/ + "pavgusb %%mm4, %%mm0\n" + "movq 9(%4), %%mm7\n" /* 8 s+lx +1*/ + "pavgusb %%mm5, %%mm1\n" + "movq (%2), %%mm2\n" + "pavgusb %%mm6, %%mm0\n" + "movq 8(%2), %%mm3\n" + + "pavgusb %%mm2, %%mm0\n" + "addl %3, %4\n" + "pavgusb %%mm3, %%mm1\n" + "movq %%mm0, (%2)\n" + + "pavgusb %%mm7, %%mm1\n" + "movq %%mm6, %%mm2\n" + "movq %%mm7, %%mm3\n" + "movq %%mm1, 8(%2)\n" + "movq %%mm4, %%mm0\n" + "movq %%mm5, %%mm1\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +} + +static inline void rec4ac_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ + __asm__ __volatile__( + "movq (%1), %%mm0\n" /* 8 s */ + "movq 1(%1), %%mm2\n" /* 8 s +1*/ + ".align 8\n" + "1:" + "movq (%4), %%mm4\n" /* 8 s+lx */ + "pavgusb %%mm2, %%mm0\n" + + "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/ + "pavgusb %%mm4, %%mm0\n" + "movq (%2), %%mm1\n" /* 8 d */ + "pavgusb %%mm6, %%mm0\n" + "addl %3, %4\n" + "pavgusb %%mm1, %%mm0\n" + "movq %%mm6, %%mm2\n" + "movq %%mm0, (%2)\n" + "movq %%mm4, %%mm0\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +} + +#else // HAVE_3DNOW + static LONGLONG ADD_1 = 0x0101010101010101LL; + static LONGLONG MASK_AND = 0x7f7f7f7f7f7f7f7fLL; +#endif + +static inline void rec_mmx(unsigned char *s, unsigned char *d, int lx2, int h) +{ + __asm__ __volatile__( + ".align 8\n" + "1:\t" + "movq ( %1 ), %%mm0\n" /* 8 s */ + "movq 8( %1 ), %%mm2\n" /* 16 s */ + "movq %%mm0, ( %2 )\n" + "addl %3, %1\n" + "movq %%mm2, 8( %2 )\n" + "decl %0\n" + "leal (%2, %3), %2\n" + "jnz 1b" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +} + + +static inline void recc_mmx(unsigned char *s, unsigned char *d, int lx2, int h) +{ + __asm__ __volatile__( + ".align 8\n" + "1:\t" + "movq ( %1 ), %%mm0\n" + "addl %3, %1\n" + "movq %%mm0, ( %2 )\n" + "decl %0\n" + "leal (%2, %3), %2\n" + "jnz 1b" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +} + + +static inline void reca_mmx(unsigned char *s, unsigned char *d, int lx2, int h) +{ +#ifdef HAVE_3Dnow + __asm__ ( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq (%2), %%mm2\n" /* 8 d */ + "movq 8(%1), %%mm1\n" /* 8 s */ + "movq 8(%2), %%mm3\n" /* 8 d */ + "pavgusb %%mm2, %%mm0\n" + "addl %3, %1\n" + "pavgusb %%mm3, %%mm1\n" + + "movq %%mm0, (%2)\n" + "movq %%mm1, 8(%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +#else /* No 3dnow */ + __asm__ ( + "movq MASK_AND, %%mm5\n" + "movq ADD_1, %%mm6\n" + "1:\t" + "movq (%1),%%mm0\n" /* Load 16 pixels from each row */ + "movq (%2),%%mm1\n" + "movq 8(%1),%%mm2\n" + "movq 8(%2),%%mm3\n" + "psrlw $1,%%mm0\n" /* Shift pixels down */ + "psrlw $1,%%mm1\n" + "pand %%mm5,%%mm0\n" /* Zero out significant bit */ + "psrlw $1,%%mm2\n" + "pand %%mm5,%%mm1\n" + "psrlw $1,%%mm3\n" + "pand %%mm5,%%mm2\n" + "paddusb %%mm1,%%mm0\n" /* Add pixels */ + "pand %%mm5,%%mm3\n" + "paddusb %%mm3,%%mm2\n" + "paddusb %%mm6,%%mm0\n" /* Add 1 to results */ + "paddusb %%mm6,%%mm2\n" + "movq %%mm0,(%2)\n" + "addl %3,%1\n" + "movq %%mm2, 8(%2)\n" + "decl %0\n" + "leal (%2, %3), %2\n" + "jnz 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +#endif +} + + +static inline void recac_mmx(unsigned char *s, unsigned char *d, int lx2, int h) +{ +#ifdef HAVE_3Dnow + __asm__ ( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq (%2), %%mm2\n" /* 8 d */ + "pavgusb %%mm2, %%mm0\n" + "addl %3, %1\n" + "movq %%mm0, (%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +#else /* No 3dnow */ + __asm__ ( + "movq MASK_AND, %%mm5\n" + "movq ADD_1, %%mm6\n" + "1:\t" + "movq (%1),%%mm0\n" + "movq (%2),%%mm1\n" + "psrlw $1,%%mm0\n" + "psrlw $1,%%mm1\n" + "pand %%mm5,%%mm0\n" + "pand %%mm5,%%mm1\n" + "paddusb %%mm1,%%mm0\n" + "paddusb %%mm6,%%mm0\n" + "addl %3,%1\n" + "movq %%mm0,(%2)\n" + "decl %0\n" + "leal (%2, %3), %2\n" + "jnz 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2) + ); +#endif +} + + +static inline void recv_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ +#ifdef HAVE_3Dnow + __asm__( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq (%4), %%mm2\n" /* 8 s +lx */ + "movq 8(%1), %%mm1\n" /* 8 s */ + "movq 8(%4), %%mm3\n" /* 8 s +lx **/ + + "pavgusb %%mm2, %%mm0\n" + "addl %3, %1\n" + "pavgusb %%mm3, %%mm1\n" + + "movq %%mm0, (%2)\n" + "addl %3, %4\n" + "movq %%mm1, 8(%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +#else + __asm__ ( + "movq MASK_AND, %%mm5\n" + "movq ADD_1, %%mm6\n" + "1:\t" + "movq (%1), %%mm0\n" /* 8 s */ + "movq (%4), %%mm1\n" /* 8 s +lx */ + "movq 8(%1), %%mm2\n" /* 8 s */ + "movq 8(%4), %%mm3\n" /* 8 s +lx **/ + "psrlw $1,%%mm0\n" + "psrlw $1,%%mm1\n" + "pand %%mm5,%%mm0\n" + "psrlw $1,%%mm2\n" + "pand %%mm5,%%mm1\n" + "psrlw $1,%%mm3\n" + "pand %%mm5,%%mm2\n" + "paddusb %%mm1,%%mm0\n" + "pand %%mm5,%%mm3\n" + "paddusb %%mm3,%%mm2\n" + "paddusb %%mm6,%%mm0\n" + "paddusb %%mm6,%%mm2\n" + "movq %%mm0,(%2)\n" + "addl %3,%1\n" + "movq %%mm2, 8(%2)\n" + "addl %3,%4\n" + "decl %0\n" + "leal (%2, %3), %2\n" + "jnz 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +#endif +} + + +static inline void recvc_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ +#ifdef HAVE_3Dnow + __asm__( + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 s */ + "movq (%4), %%mm2\n" /* 8 s +lx */ + "addl %3, %1\n" + "pavgusb %%mm2, %%mm0\n" + "addl %3, %4\n" + "movq %%mm0, (%2)\n" + "addl %3, %2\n" + "loop 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +#else + __asm__ ( + "movq MASK_AND, %%mm5\n" + "movq ADD_1, %%mm6\n" + "1:\t" + "movq (%1), %%mm0\n" /* 8 s */ + "movq (%4), %%mm1\n" /* 8 s +lx */ + "psrlw $1,%%mm0\n" + "psrlw $1,%%mm1\n" + "pand %%mm5,%%mm0\n" + "pand %%mm5,%%mm1\n" + "paddusb %%mm1,%%mm0\n" + "addl %3,%1\n" + "paddusb %%mm6,%%mm0\n" + "addl %3,%4\n" + "movq %%mm0,(%2)\n" + "decl %0\n" + "leal (%2, %3), %2\n" + "jnz 1b\n" + : + : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx) + ); +#endif +} + +#endif // HAVE_MMX + +static inline void rec(unsigned char *s, unsigned char *d, int lx2, int h) +{ + int j; + for(j = 0; j < h; j++, s += lx2, d += lx2) + { + d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3]; + d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7]; + d[8] = s[8]; d[9] = s[9]; d[10] = s[10]; d[11] = s[11]; + d[12] = s[12]; d[13] = s[13]; d[14] = s[14]; d[15] = s[15]; + } +} + + + +static inline void recc(unsigned char *s, unsigned char *d, int lx2, int h) +{ + int j; + for(j = 0; j < h; j++, s += lx2, d += lx2) + { + d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3]; + d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7]; + } +} + +static inline void reca(unsigned char *s, unsigned char *d, int lx2, int h) +{ + int j; + for(j = 0; j < h; j++, s +=lx2, d +=lx2) + { + d[0] = (unsigned int)(d[0] + s[0] + 1) >> 1; + d[1] = (unsigned int)(d[1] + s[1] + 1) >> 1; + d[2] = (unsigned int)(d[2] + s[2] + 1) >> 1; + d[3] = (unsigned int)(d[3] + s[3] + 1) >> 1; + d[4] = (unsigned int)(d[4] + s[4] + 1) >> 1; + d[5] = (unsigned int)(d[5] + s[5] + 1) >> 1; + d[6] = (unsigned int)(d[6] + s[6] + 1) >> 1; + d[7] = (unsigned int)(d[7] + s[7] + 1) >> 1; + d[8] = (unsigned int)(d[8] + s[8] + 1) >> 1; + d[9] = (unsigned int)(d[9] + s[9] + 1) >> 1; + d[10] = (unsigned int)(d[10] + s[10] + 1) >> 1; + d[11] = (unsigned int)(d[11] + s[11] + 1) >> 1; + d[12] = (unsigned int)(d[12] + s[12] + 1) >> 1; + d[13] = (unsigned int)(d[13] + s[13] + 1) >> 1; + d[14] = (unsigned int)(d[14] + s[14] + 1) >> 1; + d[15] = (unsigned int)(d[15] + s[15] + 1) >> 1; + } +} + +static inline void recac(unsigned char *s, unsigned char *d, int lx2, int h) +{ + int j; + for(j = 0; j < h; j++, s += lx2, d += lx2) + { + d[0] = (unsigned int)(d[0] + s[0] + 1)>>1; + d[1] = (unsigned int)(d[1] + s[1] + 1)>>1; + d[2] = (unsigned int)(d[2] + s[2] + 1)>>1; + d[3] = (unsigned int)(d[3] + s[3] + 1)>>1; + d[4] = (unsigned int)(d[4] + s[4] + 1)>>1; + d[5] = (unsigned int)(d[5] + s[5] + 1)>>1; + d[6] = (unsigned int)(d[6] + s[6] + 1)>>1; + d[7] = (unsigned int)(d[7] + s[7] + 1)>>1; + } +} + +static inline void recv_(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ + unsigned char *dp,*sp,*sp2; + int j; + sp = s; + sp2 = s + lx; + dp = d; + for(j = 0; j < h; j++) + { + dp[0] = (unsigned int)(sp[0] + sp2[0] + 1) >> 1; + dp[1] = (unsigned int)(sp[1] + sp2[1] + 1) >> 1; + dp[2] = (unsigned int)(sp[2] + sp2[2] + 1) >> 1; + dp[3] = (unsigned int)(sp[3] + sp2[3] + 1) >> 1; + dp[4] = (unsigned int)(sp[4] + sp2[4] + 1) >> 1; + dp[5] = (unsigned int)(sp[5] + sp2[5] + 1) >> 1; + dp[6] = (unsigned int)(sp[6] + sp2[6] + 1) >> 1; + dp[7] = (unsigned int)(sp[7] + sp2[7] + 1) >> 1; + dp[8] = (unsigned int)(sp[8] + sp2[8] + 1) >> 1; + dp[9] = (unsigned int)(sp[9] + sp2[9] + 1) >> 1; + dp[10] = (unsigned int)(sp[10] + sp2[10] + 1) >> 1; + dp[11] = (unsigned int)(sp[11] + sp2[11] + 1) >> 1; + dp[12] = (unsigned int)(sp[12] + sp2[12] + 1) >> 1; + dp[13] = (unsigned int)(sp[13] + sp2[13] + 1) >> 1; + dp[14] = (unsigned int)(sp[14] + sp2[14] + 1) >> 1; + dp[15] = (unsigned int)(sp[15] + sp2[15] + 1) >> 1; + sp+= lx2; + sp2+= lx2; + dp+= lx2; + } +} + +static inline void recvc(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ + unsigned char *dp,*sp,*sp2; + int j; + + sp = s; + sp2 = s+lx; + dp = d; + for(j = 0; j < h; j++) + { + dp[0] = (unsigned int)(sp[0]+sp2[0]+1)>>1; + dp[1] = (unsigned int)(sp[1]+sp2[1]+1)>>1; + dp[2] = (unsigned int)(sp[2]+sp2[2]+1)>>1; + dp[3] = (unsigned int)(sp[3]+sp2[3]+1)>>1; + dp[4] = (unsigned int)(sp[4]+sp2[4]+1)>>1; + dp[5] = (unsigned int)(sp[5]+sp2[5]+1)>>1; + dp[6] = (unsigned int)(sp[6]+sp2[6]+1)>>1; + dp[7] = (unsigned int)(sp[7]+sp2[7]+1)>>1; + sp+= lx2; + sp2+= lx2; + dp+= lx2; + } +} + + +static inline void recva(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ + unsigned char *dp,*sp,*sp2; + int j; + + sp = s; + sp2 = s+lx; + dp = d; + for (j=0; j>1) + 1)>>1; + dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1; + dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1; + dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1; + dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1; + dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1; + dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1; + dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1; + dp[8] = (dp[8] + ((unsigned int)(sp[8]+sp2[8]+1)>>1) + 1)>>1; + dp[9] = (dp[9] + ((unsigned int)(sp[9]+sp2[9]+1)>>1) + 1)>>1; + dp[10] = (dp[10] + ((unsigned int)(sp[10]+sp2[10]+1)>>1) + 1)>>1; + dp[11] = (dp[11] + ((unsigned int)(sp[11]+sp2[11]+1)>>1) + 1)>>1; + dp[12] = (dp[12] + ((unsigned int)(sp[12]+sp2[12]+1)>>1) + 1)>>1; + dp[13] = (dp[13] + ((unsigned int)(sp[13]+sp2[13]+1)>>1) + 1)>>1; + dp[14] = (dp[14] + ((unsigned int)(sp[14]+sp2[14]+1)>>1) + 1)>>1; + dp[15] = (dp[15] + ((unsigned int)(sp[15]+sp2[15]+1)>>1) + 1)>>1; + sp+= lx2; + sp2+= lx2; + dp+= lx2; + } +} + + +static inline void recvac(unsigned char *s, unsigned char *d, int lx,int lx2, int h){ + unsigned char *dp,*sp,*sp2; + int j; + + sp = s; + sp2 = s+lx; + dp = d; + for (j=0; j>1) + 1)>>1; + dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1; + dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1; + dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1; + dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1; + dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1; + dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1; + dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1; + sp+= lx2; + sp2+= lx2; + dp+= lx2; + } +} + + +static inline void rech(unsigned char *s, unsigned char *d, int lx2, int h){ + unsigned char *dp,*sp; + unsigned int s1,s2; + int j; + + sp = s; + dp = d; + for (j=0; j>1; + dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1; + dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1; + dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1; + dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1; + dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1; + dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1; + dp[7] = (unsigned int)(s2+(s1=sp[8])+1)>>1; + dp[8] = (unsigned int)(s1+(s2=sp[9])+1)>>1; + dp[9] = (unsigned int)(s2+(s1=sp[10])+1)>>1; + dp[10] = (unsigned int)(s1+(s2=sp[11])+1)>>1; + dp[11] = (unsigned int)(s2+(s1=sp[12])+1)>>1; + dp[12] = (unsigned int)(s1+(s2=sp[13])+1)>>1; + dp[13] = (unsigned int)(s2+(s1=sp[14])+1)>>1; + dp[14] = (unsigned int)(s1+(s2=sp[15])+1)>>1; + dp[15] = (unsigned int)(s2+sp[16]+1)>>1; + sp+= lx2; + dp+= lx2; + } +} + + +static inline void rechc(unsigned char *s,unsigned char *d, int lx2, int h){ + unsigned char *dp,*sp; + unsigned int s1,s2; + int j; + + sp = s; + dp = d; + for (j=0; j>1; + dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1; + dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1; + dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1; + dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1; + dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1; + dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1; + dp[7] = (unsigned int)(s2+sp[8]+1)>>1; + sp+= lx2; + dp+= lx2; + } +} + +static inline void recha(unsigned char *s, unsigned char *d,int lx2, int h) +{ + unsigned char *dp,*sp; + unsigned int s1,s2; + int j; + + sp = s; + dp = d; + for (j = 0; j < h; j++) + { + s1 = sp[0]; + dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1; + dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1; + dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1; + dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1; + dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1; + dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1; + dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1; + dp[7] = (dp[7] + ((unsigned int)(s2 + (s1 = sp[8]) + 1) >> 1) + 1) >> 1; + dp[8] = (dp[8] + ((unsigned int)(s1 + (s2 = sp[9]) + 1) >> 1) + 1) >> 1; + dp[9] = (dp[9] + ((unsigned int)(s2 + (s1 = sp[10]) + 1) >> 1) + 1) >> 1; + dp[10] = (dp[10] + ((unsigned int)(s1 + (s2 = sp[11]) + 1) >> 1) + 1) >> 1; + dp[11] = (dp[11] + ((unsigned int)(s2 + (s1 = sp[12]) + 1) >> 1) + 1) >> 1; + dp[12] = (dp[12] + ((unsigned int)(s1 + (s2 = sp[13]) + 1) >> 1) + 1) >> 1; + dp[13] = (dp[13] + ((unsigned int)(s2 + (s1 = sp[14]) + 1) >> 1) + 1) >> 1; + dp[14] = (dp[14] + ((unsigned int)(s1 + (s2 = sp[15]) + 1) >> 1) + 1) >> 1; + dp[15] = (dp[15] + ((unsigned int)(s2 + sp[16] + 1) >> 1) + 1) >> 1; + sp += lx2; + dp += lx2; + } +} + + +static inline void rechac(unsigned char *s,unsigned char *d, int lx2, int h) +{ + unsigned char *dp,*sp; + unsigned int s1,s2; + int j; + + sp = s; + dp = d; + for(j = 0; j < h; j++) + { + s1 = sp[0]; + dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1; + dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1; + dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1; + dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1; + dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1; + dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1; + dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1; + dp[7] = (dp[7] + ((unsigned int)(s2 + sp[8] + 1) >> 1) + 1) >> 1; + sp += lx2; + dp += lx2; + } +} + + +static inline void rec4(unsigned char *s, unsigned char *d, int lx, int lx2, int h) +{ + unsigned char *dp,*sp,*sp2; + unsigned int s1,s2,s3,s4; + int j; + + sp = s; + sp2 = s+lx; + dp = d; + for (j=0; j>2; + dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2; + dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2; + dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2; + dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2; + dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2; + dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2; + dp[7] = (unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2; + dp[8] = (unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2; + dp[9] = (unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2; + dp[10] = (unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2; + dp[11] = (unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2; + dp[12] = (unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2; + dp[13] = (unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2; + dp[14] = (unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2; + dp[15] = (unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2; + sp+= lx2; + sp2+= lx2; + dp+= lx2; + } +} + + +static inline void rec4c(unsigned char *s,unsigned char *d, int lx, int lx2, int h) +{ + unsigned char *dp,*sp,*sp2; + unsigned int s1,s2,s3,s4; + int j; + + sp = s; + sp2 = s+lx; + dp = d; + for (j=0; j>2; + dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2; + dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2; + dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2; + dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2; + dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2; + dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2; + dp[7] = (unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2; + sp+= lx2; + sp2+= lx2; + dp+= lx2; + } +} + + +static inline void rec4a(unsigned char *s,unsigned char *d, int lx, int lx2, int h) +{ + unsigned char *dp=d, *sp=s, *sp2=s+lx; + unsigned int s1, s2, s3, s4; + int j; + +/* + sp = s; + sp2 = s+lx; + dp = d; +*/ + for (j=0; j>2) + 1)>>1; + dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1; + dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1; + dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1; + dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1; + dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1; + dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1; + dp[7] = (dp[7] + ((unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2) + 1)>>1; + dp[8] = (dp[8] + ((unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2) + 1)>>1; + dp[9] = (dp[9] + ((unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2) + 1)>>1; + dp[10] = (dp[10] + ((unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2) + 1)>>1; + dp[11] = (dp[11] + ((unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2) + 1)>>1; + dp[12] = (dp[12] + ((unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2) + 1)>>1; + dp[13] = (dp[13] + ((unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2) + 1)>>1; + dp[14] = (dp[14] + ((unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2) + 1)>>1; + dp[15] = (dp[15] + ((unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2) + 1)>>1; + sp+= lx2; + sp2+= lx2; + dp+= lx2; + } +} + + +static inline void rec4ac(unsigned char *s,unsigned char *d, int lx, int lx2, int h) +{ + unsigned char *dp=d, *sp=s, *sp2=s+lx; + unsigned int s1,s2,s3,s4; + int j; + +/* + sp = s; + sp2 = s+lx; + dp = d; +*/ + for (j=0; j>2) + 1)>>1; + dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1; + dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1; + dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1; + dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1; + dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1; + dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1; + dp[7] = (dp[7] + ((unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2) + 1)>>1; + sp+= lx2; + sp2+= lx2; + dp+= lx2; + } +} + +static inline +void recon_comp(mpeg3video_t *video, + unsigned char *src, + unsigned char *dst, + int lx, + int lx2, + int w, + int h, + int x, + int y, + int dx, + int dy, + int addflag) +{ + int switcher; + unsigned char *s, *d; + +/* half pel scaling */ + switcher = (dx & 1) << 3 | (dy & 1) << 2 | w; + if(addflag) switcher |= 2; +/* origins */ + s = src + lx * (y + (dy >> 1)) + x + (dx >> 1); + d = dst + lx * y + x; + +// Accelerated functions +#ifdef HAVE_3Dnow + if(video->have_mmx) + { + switch(switcher) + { + case 0x3: reca_mmx(s, d, lx2, h); break; + case 0x2: recac_mmx(s, d, lx2, h); break; + case 0x1: rec_mmx(s, d, lx2, h); break; + case 0x0: recc_mmx(s, d, lx2, h); break; + case 0x7: recva_mmx(s, d, lx, lx2, h); break; + case 0x6: recvac_mmx(s, d, lx, lx2, h); break; + case 0x5: recv_mmx(s, d, lx, lx2, h); break; + case 0x4: recvc_mmx(s, d, lx, lx2, h); break; + case 0x9: rech_mmx(s, d, lx2, h); break; + case 0x8: rechc_mmx(s, d, lx2, h); break; + } + } + else +#endif + { + switch(switcher) + { + case 0x3: reca(s, d, lx2, h); break; + case 0x2: recac(s, d, lx2, h); break; + case 0x1: rec(s, d, lx2, h); break; + case 0x0: recc(s, d, lx2, h); break; + case 0x7: recva(s, d, lx, lx2, h); break; + case 0x6: recvac(s, d, lx, lx2, h); break; + case 0x5: recv_(s, d, lx, lx2, h); break; + case 0x4: recvc(s, d, lx, lx2, h); break; + case 0x9: rech(s, d, lx2, h); break; + case 0x8: rechc(s, d, lx2, h); break; + } + } + +// Unaccelerated functions + switch(switcher) + { + case 0xb: recha(s, d, lx2, h); break; + case 0xa: rechac(s, d, lx2, h); break; + case 0xf: rec4a(s, d, lx, lx2, h); break; + case 0xe: rec4ac(s, d, lx, lx2, h); break; + case 0xd: rec4(s, d, lx, lx2, h); break; + case 0xc: rec4c(s, d, lx, lx2, h); break; + } +} + +/* + unsigned char *src[]; * prediction source buffer * + int sfield; * prediction source field number (0 or 1) * + unsigned char *dst[]; * prediction destination buffer * + int dfield; * prediction destination field number (0 or 1)* + int lx,lx2; * horizontal offsets * + int w,h; * prediction block/sub-block width, height * + int x,y; * pixel co-ordinates of top-left sample in current MB * + int dx,dy; * horizontal, vertical motion vector * + int addflag; * add prediction error to prediction ? * +*/ +static void recon(mpeg3video_t *video, + unsigned char *src[], + int sfield, + unsigned char *dst[], + int dfield, + int lx, + int lx2, + int w, + int h, + int x, + int y, + int dx, + int dy, + int addflag) +{ + +/* Y */ + recon_comp(video, (src[0] + (sfield ? (lx2 >> 1) : 0)), + dst[0] + (dfield ? (lx2 >> 1) : 0), + lx, lx2, w, h, x, y, dx, dy, addflag); + + if(video->chroma_format != CHROMA444) + { + lx >>= 1; + dx /= 2; + lx2 >>= 1; + w = 0; + x >>= 1; + } + + if(video->chroma_format == CHROMA420) + { + h >>= 1; + dy /= 2; + y >>= 1; + } + +/* Cb */ + recon_comp(video, (src[1] + (sfield ? (lx2 >> 1) : 0)), + dst[1] + (dfield ? (lx2 >> 1) : 0), + lx, lx2, w, h, x, y, dx, dy, addflag); + +/* Cr */ + recon_comp(video, (src[2] + (sfield ? (lx2 >> 1) : 0)), + dst[2] + (dfield ? (lx2 >> 1) : 0), + lx, lx2, w, h, x, y, dx, dy, addflag); +} + +#define WIDTH 1 + +int mpeg3video_reconstruct(mpeg3video_t *video, + int bx, + int by, + int mb_type, + int motion_type, + int PMV[2][2][2], + int mv_field_sel[2][2], + int dmvector[2], + int stwtype) +{ + int currentfield; + unsigned char **predframe; + int DMV[2][2]; + int stwtop, stwbot; + + stwtop = stwtype % 3; /* 0:temporal, 1 : (spat+temp) / 2, 2 : spatial */ + stwbot = stwtype / 3; + + if((mb_type & MB_FORWARD) || (video->pict_type == P_TYPE)) + { + if(video->pict_struct == FRAME_PICTURE) + { + if((motion_type == MC_FRAME) || !(mb_type & MB_FORWARD)) + { +/* frame-based prediction */ + { + if(stwtop < 2) + recon(video, video->oldrefframe, 0, video->newframe, 0, + video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by, + PMV[0][0][0], PMV[0][0][1], stwtop); + + if(stwbot < 2) + recon(video, video->oldrefframe, 1, video->newframe, 1, + video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by, + PMV[0][0][0], PMV[0][0][1], stwbot); + } + } + else if(motion_type == MC_FIELD) /* field-based prediction */ + { +/* top field prediction */ + if(stwtop < 2) + recon(video, video->oldrefframe, mv_field_sel[0][0], video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1, + PMV[0][0][0], PMV[0][0][1] >> 1, stwtop); + +/* bottom field prediction */ + if(stwbot < 2) + recon(video, video->oldrefframe, mv_field_sel[1][0], video->newframe, 1, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1, + PMV[1][0][0], PMV[1][0][1] >> 1, stwbot); + } + else if(motion_type == MC_DMV) + { +/* dual prime prediction */ +/* calculate derived motion vectors */ + mpeg3video_calc_dmv(video, + DMV, + dmvector, + PMV[0][0][0], + PMV[0][0][1] >> 1); + + if(stwtop < 2) + { +/* predict top field from top field */ + recon(video, video->oldrefframe, 0, video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1, + PMV[0][0][0], PMV[0][0][1] >> 1, 0); + +/* predict and add to top field from bottom field */ + recon(video, video->oldrefframe, 1, video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1, + DMV[0][0], DMV[0][1], 1); + } + + if(stwbot < 2) + { +/* predict bottom field from bottom field */ + recon(video, video->oldrefframe, 1, video->newframe, 1, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1, + PMV[0][0][0], PMV[0][0][1]>>1, 0); + +/* predict and add to bottom field from top field */ + recon(video, video->oldrefframe, 0, video->newframe, 1, + video->coded_picture_width << 1, video->coded_picture_width<<1, WIDTH, 8, bx, by>>1, + DMV[1][0], DMV[1][1], 1); + } + } + else +/* invalid motion_type */ +/* fprintf(stderr, "reconstruct: invalid motion_type\n"); */ + ; + } + else + { +/* TOP_FIELD or BOTTOM_FIELD */ +/* field picture */ + currentfield = (video->pict_struct == BOTTOM_FIELD); + +/* determine which frame to use for prediction */ + if((video->pict_type == P_TYPE) && video->secondfield + && (currentfield != mv_field_sel[0][0])) + predframe = video->refframe; /* same frame */ + else + predframe = video->oldrefframe; /* previous frame */ + + if((motion_type == MC_FIELD) || !(mb_type & MB_FORWARD)) + { +/* field-based prediction */ + if(stwtop < 2) + recon(video, predframe,mv_field_sel[0][0],video->newframe,0, + video->coded_picture_width << 1,video->coded_picture_width << 1,WIDTH,16,bx,by, + PMV[0][0][0],PMV[0][0][1],stwtop); + } + else + if(motion_type == MC_16X8) + { + if(stwtop < 2) + { + recon(video, predframe, mv_field_sel[0][0], video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by, + PMV[0][0][0], PMV[0][0][1], stwtop); + + /* determine which frame to use for lower half prediction */ + if((video->pict_type==P_TYPE) && video->secondfield + && (currentfield!=mv_field_sel[1][0])) + predframe = video->refframe; /* same frame */ + else + predframe = video->oldrefframe; /* previous frame */ + + recon(video, predframe, mv_field_sel[1][0], video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8, + PMV[1][0][0], PMV[1][0][1], stwtop); + } + } + else + if(motion_type == MC_DMV) /* dual prime prediction */ + { + if(video->secondfield) + predframe = video->refframe; /* same frame */ + else + predframe = video->oldrefframe; /* previous frame */ + +/* calculate derived motion vectors */ + mpeg3video_calc_dmv(video, + DMV, + dmvector, + PMV[0][0][0], + PMV[0][0][1]); + +/* predict from field of same parity */ + recon(video, video->oldrefframe, currentfield, video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by, + PMV[0][0][0], PMV[0][0][1], 0); + +/* predict from field of opposite parity */ + recon(video, predframe, !currentfield, video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by, + DMV[0][0], DMV[0][1], 1); + } + else +/* invalid motion_type */ +/* fprintf(stderr, "reconstruct: invalid motion_type\n"); */ + ; + } + stwtop = stwbot = 1; + } + + if(mb_type & MB_BACKWARD) + { + if(video->pict_struct == FRAME_PICTURE) + { + if(motion_type == MC_FRAME) + { +/* frame-based prediction */ + if(stwtop < 2) + recon(video, video->refframe, 0, video->newframe, 0, + video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by, + PMV[0][1][0], PMV[0][1][1], stwtop); + + if(stwbot < 2) + recon(video, video->refframe, 1, video->newframe, 1, + video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by, + PMV[0][1][0], PMV[0][1][1], stwbot); + } + else + { +/* field-based prediction */ +/* top field prediction */ + if(stwtop < 2) + { + recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0, + (video->coded_picture_width << 1), (video->coded_picture_width<<1), WIDTH, 8, bx, (by >> 1), + PMV[0][1][0], (PMV[0][1][1] >> 1), stwtop); + } + +/* bottom field prediction */ + if(stwbot < 2) + { + recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 1, (video->coded_picture_width << 1), + (video->coded_picture_width << 1), WIDTH, 8, bx, (by>>1), + PMV[1][1][0], (PMV[1][1][1]>>1), stwbot); + } + } + } + else + { +/* TOP_FIELD or BOTTOM_FIELD */ +/* field picture */ + if(motion_type == MC_FIELD) + { +/* field-based prediction */ + recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by, + PMV[0][1][0], PMV[0][1][1], stwtop); + } + else if(motion_type==MC_16X8) + { + recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by, + PMV[0][1][0], PMV[0][1][1], stwtop); + + recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 0, + video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8, + PMV[1][1][0], PMV[1][1][1], stwtop); + } + else +/* invalid motion_type */ +/* fprintf(stderr, "reconstruct: invalid motion_type\n"); */ + ; + } + } /* mb_type & MB_BACKWARD */ + return 0; +} + + diff --git a/core/multimedia/opieplayer/libmpeg3/video/seek.c b/core/multimedia/opieplayer/libmpeg3/video/seek.c new file mode 100644 index 0000000..04faba4 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/seek.c @@ -0,0 +1,233 @@ +#include "../mpeg3private.h" +#include "../mpeg3protos.h" +#include "mpeg3video.h" +#include +#include + +unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream) +{ +/* Perform forwards search */ + mpeg3bits_byte_align(stream); + +/* Perform search */ + while((mpeg3bits_showbits32_noptr(stream) >> 8) != MPEG3_PACKET_START_CODE_PREFIX && + !mpeg3bits_eof(stream)) + { + mpeg3bits_getbyte_noptr(stream); + } + return mpeg3bits_showbits32_noptr(stream); +} + +/* Line up on the beginning of the next code. */ +int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code) +{ + while(!mpeg3bits_eof(stream) && + mpeg3bits_showbits32_noptr(stream) != code) + { + mpeg3bits_getbyte_noptr(stream); + } + return mpeg3bits_eof(stream); +} + +/* Line up on the beginning of the previous code. */ +int mpeg3video_prev_code(mpeg3_bits_t* stream, unsigned int code) +{ + while(!mpeg3bits_bof(stream) && + mpeg3bits_showbits_reverse(stream, 32) != code) + { + mpeg3bits_getbits_reverse(stream, 8); + } + return mpeg3bits_bof(stream); +} + +long mpeg3video_goptimecode_to_frame(mpeg3video_t *video) +{ +/* printf("mpeg3video_goptimecode_to_frame %d %d %d %d %f\n", */ +/* video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, video->frame_rate); */ + return (long)(video->gop_timecode.hour * 3600 * video->frame_rate + + video->gop_timecode.minute * 60 * video->frame_rate + + video->gop_timecode.second * video->frame_rate + + video->gop_timecode.frame) - 1 - video->first_frame; +} + +int mpeg3video_match_refframes(mpeg3video_t *video) +{ + unsigned char *dst, *src; + int i, j, size; + + for(i = 0; i < 3; i++) + { + if(video->newframe[i]) + { + if(video->newframe[i] == video->refframe[i]) + { + src = video->refframe[i]; + dst = video->oldrefframe[i]; + } + else + { + src = video->oldrefframe[i]; + dst = video->refframe[i]; + } + + if(i == 0) + size = video->coded_picture_width * video->coded_picture_height + 32 * video->coded_picture_width; + else + size = video->chrom_width * video->chrom_height + 32 * video->chrom_width; + + memcpy(dst, src, size); + } + } + return 0; +} + +int mpeg3video_seek(mpeg3video_t *video) +{ + long this_gop_start; + int result = 0; + int back_step; + int attempts; + mpeg3_t *file = video->file; + mpeg3_bits_t *vstream = video->vstream; + double percentage; + long frame_number; + int match_refframes = 1; + +/* Seek to a percentage */ + if(video->percentage_seek >= 0) + { + percentage = video->percentage_seek; + video->percentage_seek = -1; + mpeg3bits_seek_percentage(vstream, percentage); +// Go to previous I-frame + mpeg3bits_start_reverse(vstream); + result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE); + if(!result) mpeg3bits_getbits_reverse(vstream, 32); + mpeg3bits_start_forward(vstream); + + if(mpeg3bits_tell_percentage(vstream) < 0) mpeg3bits_seek_percentage(vstream, 0); + +// Read up to the correct percentage + result = 0; + while(!result && mpeg3bits_tell_percentage(vstream) < percentage) + { + result = mpeg3video_read_frame_backend(video, 0); + if(match_refframes) + mpeg3video_match_refframes(video); + match_refframes = 0; + } + } + else +/* Seek to a frame */ + if(video->frame_seek >= 0) + { + frame_number = video->frame_seek; + video->frame_seek = -1; + if(frame_number < 0) frame_number = 0; + if(frame_number > video->maxframe) frame_number = video->maxframe; + +/* Seek to start of file */ + if(frame_number < 16) + { + video->repeat_count = video->current_repeat = 0; + mpeg3bits_seek_start(vstream); + video->framenum = 0; + result = mpeg3video_drop_frames(video, frame_number - video->framenum); + } + else + { +/* Seek to an I frame. */ + if((frame_number < video->framenum || frame_number - video->framenum > MPEG3_SEEK_THRESHOLD)) + { +/* Elementary stream */ + if(file->is_video_stream) + { + mpeg3_t *file = video->file; + mpeg3_vtrack_t *track = video->track; + long byte = (long)((float)(mpeg3demuxer_total_bytes(vstream->demuxer) / + track->total_frames) * + frame_number); + long minimum = 65535; + int done = 0; + +//printf("seek elementary %d\n", frame_number); +/* Get GOP just before frame */ + do + { + result = mpeg3bits_seek_byte(vstream, byte); + mpeg3bits_start_reverse(vstream); + if(!result) result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE); + mpeg3bits_start_forward(vstream); + mpeg3bits_getbits(vstream, 8); + if(!result) result = mpeg3video_getgophdr(video); + this_gop_start = mpeg3video_goptimecode_to_frame(video); + +//printf("wanted %ld guessed %ld byte %ld result %d\n", frame_number, this_gop_start, byte, result); + if(labs(this_gop_start - frame_number) >= labs(minimum)) + done = 1; + else + { + minimum = this_gop_start - frame_number; + byte += (long)((float)(frame_number - this_gop_start) * + (float)(mpeg3demuxer_total_bytes(vstream->demuxer) / + track->total_frames)); + if(byte < 0) byte = 0; + } + }while(!result && !done); + +//printf("wanted %d guessed %d\n", frame_number, this_gop_start); + if(!result) + { + video->framenum = this_gop_start; + result = mpeg3video_drop_frames(video, frame_number - video->framenum); + } + } + else +/* System stream */ + { + mpeg3bits_seek_time(vstream, (double)frame_number / video->frame_rate); + percentage = mpeg3bits_tell_percentage(vstream); +//printf("seek frame %ld percentage %f byte %ld\n", frame_number, percentage, mpeg3bits_tell(vstream)); + mpeg3bits_start_reverse(vstream); + mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE); + mpeg3bits_getbits_reverse(vstream, 32); + mpeg3bits_start_forward(vstream); +//printf("seek system 1 %f\n", (double)frame_number / video->frame_rate); + + while(!result && mpeg3bits_tell_percentage(vstream) < percentage) + { + result = mpeg3video_read_frame_backend(video, 0); + if(match_refframes) + mpeg3video_match_refframes(video); + +//printf("seek system 2 %f %f\n", mpeg3bits_tell_percentage(vstream) / percentage); + match_refframes = 0; + } +//printf("seek system 3 %f\n", (double)frame_number / video->frame_rate); + } + + video->framenum = frame_number; + } + else +// Drop frames + { + mpeg3video_drop_frames(video, frame_number - video->framenum); + } + } + } + + return result; +} + +int mpeg3video_drop_frames(mpeg3video_t *video, long frames) +{ + int result = 0; + long frame_number = video->framenum + frames; + +/* Read the selected number of frames and skip b-frames */ + while(!result && frame_number > video->framenum) + { + result = mpeg3video_read_frame_backend(video, frame_number - video->framenum); + } + return result; +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/slice.c b/core/multimedia/opieplayer/libmpeg3/video/slice.c new file mode 100644 index 0000000..90891b0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/slice.c @@ -0,0 +1,702 @@ +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "mpeg3video.h" +#include "mpeg3videoprotos.h" +#include "slice.h" + +#include + +static ULONGLONG MMX_128 = 0x80008000800080LL; + +int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer) +{ + pthread_mutexattr_t mutex_attr; + slice_buffer->data = (unsigned char*)malloc(1024); + slice_buffer->buffer_size = 0; + slice_buffer->buffer_allocation = 1024; + slice_buffer->current_position = 0; + slice_buffer->bits_size = 0; + slice_buffer->bits = 0; + slice_buffer->done = 0; + pthread_mutexattr_init(&mutex_attr); + pthread_mutex_init(&(slice_buffer->completion_lock), &mutex_attr); + return 0; +} + +int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer) +{ + free(slice_buffer->data); + pthread_mutex_destroy(&(slice_buffer->completion_lock)); + return 0; +} + +int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer) +{ + int i; + unsigned char *new_buffer = + (unsigned char*)malloc(slice_buffer->buffer_allocation * 2); + for(i = 0; i < slice_buffer->buffer_size; i++) + new_buffer[i] = slice_buffer->data[i]; + free(slice_buffer->data); + slice_buffer->data = new_buffer; + slice_buffer->buffer_allocation *= 2; + return 0; +} + +/* limit coefficients to -2048..2047 */ + +/* move/add 8x8-Block from block[comp] to refframe */ + +static inline int mpeg3video_addblock(mpeg3_slice_t *slice, + mpeg3video_t *video, + int comp, + int bx, + int by, + int dct_type, + int addflag) +{ + int cc, i, iincr; + unsigned char *rfp; + short *bp; + int spar = slice->sparse[comp]; +/* color component index */ + cc = (comp < 4) ? 0 : (comp & 1) + 1; + + if(cc == 0) + { +/* luminance */ + if(video->pict_struct == FRAME_PICTURE) + { + if(dct_type) + { +/* field DCT coding */ + rfp = video->newframe[0] + + video->coded_picture_width * (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3); + iincr = (video->coded_picture_width << 1); + } + else + { +/* frame DCT coding */ + rfp = video->newframe[0] + + video->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3); + iincr = video->coded_picture_width; + } + } + else + { +/* field picture */ + rfp = video->newframe[0] + + (video->coded_picture_width << 1) * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3); + iincr = (video->coded_picture_width << 1); + } + } + else + { +/* chrominance */ + +/* scale coordinates */ + if(video->chroma_format != CHROMA444) bx >>= 1; + if(video->chroma_format == CHROMA420) by >>= 1; + if(video->pict_struct == FRAME_PICTURE) + { + if(dct_type && (video->chroma_format != CHROMA420)) + { +/* field DCT coding */ + rfp = video->newframe[cc] + + video->chrom_width * (by + ((comp & 2) >> 1)) + bx + (comp & 8); + iincr = (video->chrom_width << 1); + } + else + { +/* frame DCT coding */ + rfp = video->newframe[cc] + + video->chrom_width * (by + ((comp & 2) << 2)) + bx + (comp & 8); + iincr = video->chrom_width; + } + } + else + { +/* field picture */ + rfp = video->newframe[cc] + + (video->chrom_width << 1) * (by + ((comp & 2) << 2)) + bx + (comp & 8); + iincr = (video->chrom_width << 1); + } + } + + bp = slice->block[comp]; + + if(addflag) + { +#ifdef HAVE_MMX + if(video->have_mmx) + { + if(spar) + { + __asm__ __volatile__( + "movq (%2), %%mm6\n" /* 4 blockvals */ + "pxor %%mm4, %%mm4\n" + "punpcklwd %%mm6, %%mm6\n" + "punpcklwd %%mm6, %%mm6\n" + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" /* 8 rindex1 */ + "movq %%mm0, %%mm2\n" + "punpcklbw %%mm4, %%mm0\n" + "punpckhbw %%mm4, %%mm2\n" + "paddw %%mm6, %%mm0\n" + "paddw %%mm6, %%mm2\n" + + "packuswb %%mm2, %%mm0\n" + "movq %%mm0, (%1)\n" + + "leal (%1, %3), %1\n" + "loop 1b\n" + : /* scr dest */ + : "c" (8),"r" (rfp), "r" (bp), "r" (iincr) + ); + } + else + { + __asm__ __volatile__( + "pxor %%mm4, %%mm4\n" + + ".align 8\n" + "1:" + "movq (%2), %%mm0\n" /* 8 rfp 0 1 2 3 4 5 6 7*/ + "movq (%1), %%mm6\n" /* 4 blockvals 0 1 2 3 */ + + "movq %%mm0, %%mm2\n" + "movq 8(%1), %%mm5\n" /* 4 blockvals 0 1 2 3 */ + "punpcklbw %%mm4, %%mm0\n" /* 0 2 4 6 */ + "punpckhbw %%mm4, %%mm2\n" /* 1 3 5 7 */ + + "paddw %%mm6, %%mm0\n" + "paddw %%mm5, %%mm2\n" + "packuswb %%mm2, %%mm0\n" + + "addl $16, %1\n" + "movq %%mm0, (%2)\n" + + "leal (%2,%3), %2\n" + "loop 1b\n" + : /* scr dest */ + : "c" (8),"r" (bp), "r" (rfp), "r" (iincr) + ); + } + } + else +#endif + for(i = 0; i < 8; i++) + { + rfp[0] = CLIP(bp[0] + rfp[0]); + rfp[1] = CLIP(bp[1] + rfp[1]); + rfp[2] = CLIP(bp[2] + rfp[2]); + rfp[3] = CLIP(bp[3] + rfp[3]); + rfp[4] = CLIP(bp[4] + rfp[4]); + rfp[5] = CLIP(bp[5] + rfp[5]); + rfp[6] = CLIP(bp[6] + rfp[6]); + rfp[7] = CLIP(bp[7] + rfp[7]); + rfp += iincr; + bp += 8; + } + } + else + { +#ifdef HAVE_MMX + if(video->have_mmx) + { + if(spar) + { + __asm__ __volatile__( + "movd (%2), %%mm0\n" /* " 0 0 0 v1" */ + "punpcklwd %%mm0, %%mm0\n" /* " 0 0 v1 v1" */ + "punpcklwd %%mm0, %%mm0\n" + "paddw MMX_128, %%mm0\n" + "packuswb %%mm0, %%mm0\n" + "leal (%0,%1,2), %%eax\n" + + "movq %%mm0, (%0, %1)\n" + "movq %%mm0, (%%eax)\n" + "leal (%%eax,%1,2), %0\n" + "movq %%mm0, (%%eax, %1)\n" + + "movq %%mm0, (%0)\n" + "leal (%0,%1,2), %%eax\n" + "movq %%mm0, (%0, %1)\n" + + "movq %%mm0, (%%eax)\n" + "movq %%mm0, (%%eax, %1)\n" + : + : "D" (rfp), "c" (iincr), "b" (bp) + : "eax"); + } + else + { + __asm__ __volatile__( + "movq MMX_128,%%mm4\n" + ".align 8\n" + "1:" + "movq (%1), %%mm0\n" + "movq 8(%1), %%mm1\n" + "paddw %%mm4, %%mm0\n" + + "movq 16(%1), %%mm2\n" + "paddw %%mm4, %%mm1\n" + + "movq 24(%1), %%mm3\n" + "paddw %%mm4, %%mm2\n" + + "packuswb %%mm1, %%mm0\n" + "paddw %%mm4, %%mm3\n" + + "addl $32, %1\n" + "packuswb %%mm3, %%mm2\n" + + "movq %%mm0, (%2)\n" + + "movq %%mm2, (%2,%3)\n" + + "leal (%2,%3,2), %2\n" + "loop 1b\n" + : + : "c" (4), "r" (bp), "r" (rfp), "r" (iincr) + ); + } + } + else +#endif + for(i = 0; i < 8; i++) + { + rfp[0] = CLIP(bp[0] + 128); + rfp[1] = CLIP(bp[1] + 128); + rfp[2] = CLIP(bp[2] + 128); + rfp[3] = CLIP(bp[3] + 128); + rfp[4] = CLIP(bp[4] + 128); + rfp[5] = CLIP(bp[5] + 128); + rfp[6] = CLIP(bp[6] + 128); + rfp[7] = CLIP(bp[7] + 128); + rfp+= iincr; + bp += 8; + } + } + return 0; +} + +int mpeg3_decode_slice(mpeg3_slice_t *slice) +{ + mpeg3video_t *video = slice->video; + int comp; + int mb_type, cbp, motion_type = 0, dct_type; + int macroblock_address, mba_inc, mba_max; + int slice_vert_pos_ext; + unsigned int code; + int bx, by; + int dc_dct_pred[3]; + int mv_count, mv_format, mvscale; + int pmv[2][2][2], mv_field_sel[2][2]; + int dmv, dmvector[2]; + int qs; + int stwtype, stwclass; + int snr_cbp; + int i; + mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; + +/* number of macroblocks per picture */ + mba_max = video->mb_width * video->mb_height; + +/* field picture has half as many macroblocks as frame */ + if(video->pict_struct != FRAME_PICTURE) + mba_max >>= 1; + +/* macroblock address */ + macroblock_address = 0; +/* first macroblock in slice is not skipped */ + mba_inc = 0; + slice->fault = 0; + + code = mpeg3slice_getbits(slice_buffer, 32); +/* decode slice header (may change quant_scale) */ + slice_vert_pos_ext = mpeg3video_getslicehdr(slice, video); + +/* reset all DC coefficient and motion vector predictors */ + dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; + pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; + pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; + + for(i = 0; + slice_buffer->current_position < slice_buffer->buffer_size; + i++) + { + if(mba_inc == 0) + { +/* Done */ + if(!mpeg3slice_showbits(slice_buffer, 23)) return 0; +/* decode macroblock address increment */ + mba_inc = mpeg3video_get_macroblock_address(slice); + + if(slice->fault) return 1; + + if(i == 0) + { +/* Get the macroblock_address */ + macroblock_address = ((slice_vert_pos_ext << 7) + (code & 255) - 1) * video->mb_width + mba_inc - 1; +/* first macroblock in slice: not skipped */ + mba_inc = 1; + } + } + + if(slice->fault) return 1; + + if(macroblock_address >= mba_max) + { +/* mba_inc points beyond picture dimensions */ + /*fprintf(stderr, "mpeg3_decode_slice: too many macroblocks in picture\n"); */ + return 1; + } + +/* not skipped */ + if(mba_inc == 1) + { + mpeg3video_macroblock_modes(slice, + video, + &mb_type, + &stwtype, + &stwclass, + &motion_type, + &mv_count, + &mv_format, + &dmv, + &mvscale, + &dct_type); + + if(slice->fault) return 1; + + if(mb_type & MB_QUANT) + { + qs = mpeg3slice_getbits(slice_buffer, 5); + + if(video->mpeg2) + slice->quant_scale = video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1); + else + slice->quant_scale = qs; + + if(video->scalable_mode == SC_DP) +/* make sure quant_scale is valid */ + slice->quant_scale = slice->quant_scale; + } + +/* motion vectors */ + + +/* decode forward motion vectors */ + if((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && video->conceal_mv)) + { + if(video->mpeg2) + mpeg3video_motion_vectors(slice, + video, + pmv, + dmvector, + mv_field_sel, + 0, + mv_count, + mv_format, + video->h_forw_r_size, + video->v_forw_r_size, + dmv, + mvscale); + else + mpeg3video_motion_vector(slice, + video, + pmv[0][0], + dmvector, + video->forw_r_size, + video->forw_r_size, + 0, + 0, + video->full_forw); + } + if(slice->fault) return 1; + +/* decode backward motion vectors */ + if(mb_type & MB_BACKWARD) + { + if(video->mpeg2) + mpeg3video_motion_vectors(slice, + video, + pmv, + dmvector, + mv_field_sel, + 1, + mv_count, + mv_format, + video->h_back_r_size, + video->v_back_r_size, + 0, + mvscale); + else + mpeg3video_motion_vector(slice, + video, + pmv[0][1], + dmvector, + video->back_r_size, + video->back_r_size, + 0, + 0, + video->full_back); + } + + if(slice->fault) return 1; + +/* remove marker_bit */ + if((mb_type & MB_INTRA) && video->conceal_mv) + mpeg3slice_flushbit(slice_buffer); + +/* macroblock_pattern */ + if(mb_type & MB_PATTERN) + { + cbp = mpeg3video_get_cbp(slice); + if(video->chroma_format == CHROMA422) + { +/* coded_block_pattern_1 */ + cbp = (cbp << 2) | mpeg3slice_getbits2(slice_buffer); + } + else + if(video->chroma_format == CHROMA444) + { +/* coded_block_pattern_2 */ + cbp = (cbp << 6) | mpeg3slice_getbits(slice_buffer, 6); + } + } + else + cbp = (mb_type & MB_INTRA) ? ((1 << video->blk_cnt) - 1) : 0; + + if(slice->fault) return 1; +/* decode blocks */ + mpeg3video_clearblock(slice, 0, video->blk_cnt); + for(comp = 0; comp < video->blk_cnt; comp++) + { + if(cbp & (1 << (video->blk_cnt - comp - 1))) + { + if(mb_type & MB_INTRA) + { + if(video->mpeg2) + mpeg3video_getmpg2intrablock(slice, video, comp, dc_dct_pred); + else + mpeg3video_getintrablock(slice, video, comp, dc_dct_pred); + } + else + { + if(video->mpeg2) + mpeg3video_getmpg2interblock(slice, video, comp); + else + mpeg3video_getinterblock(slice, video, comp); + } + if(slice->fault) return 1; + } + } + +/* reset intra_dc predictors */ + if(!(mb_type & MB_INTRA)) + dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; + +/* reset motion vector predictors */ + if((mb_type & MB_INTRA) && !video->conceal_mv) + { +/* intra mb without concealment motion vectors */ + pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; + pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; + } + + if((video->pict_type == P_TYPE) && !(mb_type & (MB_FORWARD | MB_INTRA))) + { +/* non-intra mb without forward mv in a P picture */ + pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; + +/* derive motion_type */ + if(video->pict_struct == FRAME_PICTURE) + motion_type = MC_FRAME; + else + { + motion_type = MC_FIELD; +/* predict from field of same parity */ + mv_field_sel[0][0] = (video->pict_struct == BOTTOM_FIELD); + } + } + + if(stwclass == 4) + { +/* purely spatially predicted macroblock */ + pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; + pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; + } + } + else + { +/* mba_inc!=1: skipped macroblock */ + mpeg3video_clearblock(slice, 0, video->blk_cnt); + +/* reset intra_dc predictors */ + dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; + +/* reset motion vector predictors */ + if(video->pict_type == P_TYPE) + pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; + +/* derive motion_type */ + if(video->pict_struct == FRAME_PICTURE) + motion_type = MC_FRAME; + else + { + motion_type = MC_FIELD; +/* predict from field of same parity */ + mv_field_sel[0][0] = mv_field_sel[0][1] = (video->pict_struct == BOTTOM_FIELD); + } + +/* skipped I are spatial-only predicted, */ +/* skipped P and B are temporal-only predicted */ + stwtype = (video->pict_type == I_TYPE) ? 8 : 0; + +/* clear MB_INTRA */ + mb_type &= ~MB_INTRA; + +/* no block data */ + cbp = 0; + } + + snr_cbp = 0; + +/* pixel coordinates of top left corner of current macroblock */ + bx = 16 * (macroblock_address % video->mb_width); + by = 16 * (macroblock_address / video->mb_width); + +/* motion compensation */ + if(!(mb_type & MB_INTRA)) + mpeg3video_reconstruct(video, + bx, + by, + mb_type, + motion_type, + pmv, + mv_field_sel, + dmvector, + stwtype); + +/* copy or add block data into picture */ + for(comp = 0; comp < video->blk_cnt; comp++) + { + if((cbp | snr_cbp) & (1 << (video->blk_cnt - 1 - comp))) + { +#ifdef HAVE_MMX + if(video->have_mmx) + IDCT_mmx(slice->block[comp]); + else +#endif + mpeg3video_idct_conversion(slice->block[comp]); + + mpeg3video_addblock(slice, + video, + comp, + bx, + by, + dct_type, + (mb_type & MB_INTRA) == 0); + } + } + +/* advance to next macroblock */ + macroblock_address++; + mba_inc--; + } + + return 0; +} + +void mpeg3_slice_loop(mpeg3_slice_t *slice) +{ + mpeg3video_t *video = slice->video; + int result = 1; + + while(!slice->done) + { + pthread_mutex_lock(&(slice->input_lock)); + + if(!slice->done) + { +/* Get a buffer to decode */ + result = 1; + pthread_mutex_lock(&(video->slice_lock)); + if(slice->buffer_step > 0) + { + while(slice->current_buffer <= slice->last_buffer) + { + if(!video->slice_buffers[slice->current_buffer].done && + slice->current_buffer <= slice->last_buffer) + { + result = 0; + break; + } + slice->current_buffer += slice->buffer_step; + } + } + else + { + while(slice->current_buffer >= slice->last_buffer) + { + if(!video->slice_buffers[slice->current_buffer].done && + slice->current_buffer >= slice->last_buffer) + { + result = 0; + break; + } + slice->current_buffer += slice->buffer_step; + } + } + +/* Got one */ + if(!result && slice->current_buffer >= 0 && slice->current_buffer < video->total_slice_buffers) + { + slice->slice_buffer = &(video->slice_buffers[slice->current_buffer]); + slice->slice_buffer->done = 1; + pthread_mutex_unlock(&(video->slice_lock)); + pthread_mutex_unlock(&(slice->input_lock)); + mpeg3_decode_slice(slice); + pthread_mutex_unlock(&(slice->slice_buffer->completion_lock)); + } + else + pthread_mutex_unlock(&(video->slice_lock)); + } + + pthread_mutex_unlock(&(slice->output_lock)); + } +} + +int mpeg3_new_slice_decoder(mpeg3video_t *video, mpeg3_slice_t *slice) +{ + pthread_attr_t attr; + //struct sched_param param; + pthread_mutexattr_t mutex_attr; + + slice->video = video; + slice->done = 0; + pthread_mutexattr_init(&mutex_attr); + pthread_mutex_init(&(slice->input_lock), &mutex_attr); + pthread_mutex_lock(&(slice->input_lock)); + pthread_mutex_init(&(slice->output_lock), &mutex_attr); + pthread_mutex_lock(&(slice->output_lock)); + + pthread_attr_init(&attr); + pthread_create(&(slice->tid), &attr, + (void * (*)(void *))mpeg3_slice_loop, slice); + + return 0; +} + +int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice) +{ + slice->done = 1; + pthread_mutex_unlock(&(slice->input_lock)); + pthread_join(slice->tid, 0); + pthread_mutex_destroy(&(slice->input_lock)); + pthread_mutex_destroy(&(slice->output_lock)); + return 0; +} diff --git a/core/multimedia/opieplayer/libmpeg3/video/slice.h b/core/multimedia/opieplayer/libmpeg3/video/slice.h new file mode 100644 index 0000000..e36ffef --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/slice.h @@ -0,0 +1,194 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef SLICE_H +#define SLICE_H + +#ifndef _WIN32 +#include +#endif + +/* Array of these feeds the slice decoders */ +typedef struct +{ + unsigned char *data; /* Buffer for holding the slice data */ + int buffer_size; /* Size of buffer */ + int buffer_allocation; /* Space allocated for buffer */ + int current_position; /* Position in buffer */ + unsigned MPEG3_INT32 bits; + int bits_size; + pthread_mutex_t completion_lock; /* Lock slice until completion */ + int done; /* Signal for slice decoder to skip */ +} mpeg3_slice_buffer_t; + +/* Each slice decoder */ +typedef struct +{ + struct mpeg3video_rec *video; + mpeg3_slice_buffer_t *slice_buffer; + + int thread_number; /* Number of this thread */ + int current_buffer; /* Buffer this slice decoder is on */ + int buffer_step; /* Number of buffers to skip */ + int last_buffer; /* Last buffer this decoder should process */ + int fault; + int done; + int quant_scale; + int pri_brk; /* slice/macroblock */ + short block[12][64]; + int sparse[12]; + pthread_t tid; /* ID of thread */ + pthread_mutex_t input_lock, output_lock; +} mpeg3_slice_t; + +#define mpeg3slice_fillbits(buffer, nbits) \ + while(((mpeg3_slice_buffer_t*)(buffer))->bits_size < (nbits)) \ + { \ + if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \ + { \ + ((mpeg3_slice_buffer_t*)(buffer))->bits <<= 8; \ + ((mpeg3_slice_buffer_t*)(buffer))->bits |= ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \ + } \ + ((mpeg3_slice_buffer_t*)(buffer))->bits_size += 8; \ + } + +#define mpeg3slice_flushbits(buffer, nbits) \ + { \ + mpeg3slice_fillbits((buffer), (nbits)); \ + ((mpeg3_slice_buffer_t*)(buffer))->bits_size -= (nbits); \ + } + +#define mpeg3slice_flushbit(buffer) \ +{ \ + if(((mpeg3_slice_buffer_t*)(buffer))->bits_size) \ + ((mpeg3_slice_buffer_t*)(buffer))->bits_size--; \ + else \ + if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \ + { \ + ((mpeg3_slice_buffer_t*)(buffer))->bits = \ + ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \ + ((mpeg3_slice_buffer_t*)(buffer))->bits_size = 7; \ + } \ +} + +extern inline unsigned int mpeg3slice_getbit(mpeg3_slice_buffer_t *buffer) +{ + if(buffer->bits_size) + return (buffer->bits >> (--buffer->bits_size)) & 0x1; + else + if(buffer->current_position < buffer->buffer_size) + { + buffer->bits = buffer->data[buffer->current_position++]; + buffer->bits_size = 7; + return (buffer->bits >> 7) & 0x1; + } + return 0; // WWA - stop warn +} + +extern inline unsigned int mpeg3slice_getbits2(mpeg3_slice_buffer_t *buffer) +{ + if(buffer->bits_size >= 2) + return (buffer->bits >> (buffer->bits_size -= 2)) & 0x3; + else + if(buffer->current_position < buffer->buffer_size) + { + buffer->bits <<= 8; + buffer->bits |= buffer->data[buffer->current_position++]; + buffer->bits_size += 6; + return (buffer->bits >> buffer->bits_size) & 0x3; + } + return 0; // WWA - stop warn +} + +extern inline unsigned int mpeg3slice_getbyte(mpeg3_slice_buffer_t *buffer) +{ + if(buffer->bits_size >= 8) + return (buffer->bits >> (buffer->bits_size -= 8)) & 0xff; + else + if(buffer->current_position < buffer->buffer_size) + { + buffer->bits <<= 8; + buffer->bits |= buffer->data[buffer->current_position++]; + return (buffer->bits >> buffer->bits_size) & 0xff; + } + return 0; // WWA - stop warn +} + + +extern inline unsigned int mpeg3slice_getbits(mpeg3_slice_buffer_t *slice_buffer, int bits) +{ + if(bits == 1) return mpeg3slice_getbit(slice_buffer); + mpeg3slice_fillbits(slice_buffer, bits); + return (slice_buffer->bits >> (slice_buffer->bits_size -= bits)) & (0xffffffff >> (32 - bits)); +} + +extern inline unsigned int mpeg3slice_showbits16(mpeg3_slice_buffer_t *buffer) +{ + if(buffer->bits_size >= 16) + return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff; + else + if(buffer->current_position < buffer->buffer_size) + { + buffer->bits <<= 16; + buffer->bits_size += 16; + buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8; + buffer->bits |= buffer->data[buffer->current_position++]; + return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff; + } + return 0; // WWA - stop warn +} + +extern inline unsigned int mpeg3slice_showbits9(mpeg3_slice_buffer_t *buffer) +{ + if(buffer->bits_size >= 9) + return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff; + else + if(buffer->current_position < buffer->buffer_size) + { + buffer->bits <<= 16; + buffer->bits_size += 16; + buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8; + buffer->bits |= buffer->data[buffer->current_position++]; + return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff; + } + return 0; // WWA - stop warn +} + +extern inline unsigned int mpeg3slice_showbits5(mpeg3_slice_buffer_t *buffer) +{ + if(buffer->bits_size >= 5) + return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f; + else + if(buffer->current_position < buffer->buffer_size) + { + buffer->bits <<= 8; + buffer->bits_size += 8; + buffer->bits |= buffer->data[buffer->current_position++]; + return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f; + } + return 0; // WWA - stop warn +} + +extern inline unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits) +{ + mpeg3slice_fillbits(slice_buffer, bits); + return (slice_buffer->bits >> (slice_buffer->bits_size - bits)) & (0xffffffff >> (32 - bits)); +} + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/video/vlc.c b/core/multimedia/opieplayer/libmpeg3/video/vlc.c new file mode 100644 index 0000000..4328d8a --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/vlc.c @@ -0,0 +1,421 @@ +#include "mpeg3video.h" +#include "vlc.h" + +/* variable length code tables */ + +/* Table B-3, mb_type in P-pictures, codes 001..1xx */ +mpeg3_VLCtab_t mpeg3_PMBtab0[8] = { + {ERROR,0}, + {MB_FORWARD,3}, + {MB_PATTERN,2}, {MB_PATTERN,2}, + {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1}, + {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1} +}; + +/* Table B-3, mb_type in P-pictures, codes 000001..00011x */ +mpeg3_VLCtab_t mpeg3_PMBtab1[8] = { + {ERROR,0}, + {MB_QUANT|MB_INTRA,6}, + {MB_QUANT|MB_PATTERN,5}, {MB_QUANT|MB_PATTERN,5}, + {MB_QUANT|MB_FORWARD|MB_PATTERN,5}, {MB_QUANT|MB_FORWARD|MB_PATTERN,5}, + {MB_INTRA,5}, {MB_INTRA,5} +}; + +/* Table B-4, mb_type in B-pictures, codes 0010..11xx */ +mpeg3_VLCtab_t mpeg3_BMBtab0[16] = { + {ERROR,0}, {ERROR,0}, + {MB_FORWARD,4}, + {MB_FORWARD|MB_PATTERN,4}, + {MB_BACKWARD,3}, {MB_BACKWARD,3}, + {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3}, + {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, + {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, + {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, + {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, + {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, + {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2} +}; + +/* Table B-4, mb_type in B-pictures, codes 000001..00011x */ +mpeg3_VLCtab_t mpeg3_BMBtab1[8] = { + {ERROR,0}, + {MB_QUANT|MB_INTRA,6}, + {MB_QUANT|MB_BACKWARD|MB_PATTERN,6}, + {MB_QUANT|MB_FORWARD|MB_PATTERN,6}, + {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5}, + {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5}, + {MB_INTRA,5}, {MB_INTRA,5} +}; + +/* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */ +mpeg3_VLCtab_t mpeg3_spIMBtab[16] = { + {ERROR,0}, + {MB_CLASS4,4}, + {MB_QUANT|MB_INTRA,4}, + {MB_INTRA,4}, + {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, + {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, + {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, + {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, + {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, + {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1} +}; + +/* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */ +mpeg3_VLCtab_t mpeg3_spPMBtab0[16] = +{ + {ERROR,0},{ERROR,0}, + {MB_FORWARD,4}, + {MB_WEIGHT|MB_FORWARD,4}, + {MB_QUANT|MB_FORWARD|MB_PATTERN,3}, {MB_QUANT|MB_FORWARD|MB_PATTERN,3}, + {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3}, + {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2}, + {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2}, + {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}, + {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}, + {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}, + {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2} +}; + +/* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */ +mpeg3_VLCtab_t mpeg3_spPMBtab1[16] = { + {ERROR,0},{ERROR,0}, + {MB_CLASS4|MB_QUANT|MB_PATTERN,7}, + {MB_CLASS4,7}, + {MB_PATTERN,7}, + {MB_CLASS4|MB_PATTERN,7}, + {MB_QUANT|MB_INTRA,7}, + {MB_INTRA,7}, + {MB_QUANT|MB_PATTERN,6}, {MB_QUANT|MB_PATTERN,6}, + {MB_WEIGHT|MB_QUANT|MB_PATTERN,6}, {MB_WEIGHT|MB_QUANT|MB_PATTERN,6}, + {MB_WEIGHT,6}, {MB_WEIGHT,6}, + {MB_WEIGHT|MB_PATTERN,6}, {MB_WEIGHT|MB_PATTERN,6} +}; + +/* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */ +mpeg3_VLCtab_t mpeg3_spBMBtab0[14] = { + {MB_FORWARD,4}, + {MB_FORWARD|MB_PATTERN,4}, + {MB_BACKWARD,3}, {MB_BACKWARD,3}, + {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3}, + {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, + {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, + {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, + {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, + {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, + {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2} +}; + +/* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */ +mpeg3_VLCtab_t mpeg3_spBMBtab1[12] = { + {MB_QUANT|MB_FORWARD|MB_PATTERN,7}, + {MB_QUANT|MB_BACKWARD|MB_PATTERN,7}, + {MB_INTRA,7}, + {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,7}, + {MB_WEIGHT|MB_FORWARD,6}, {MB_WEIGHT|MB_FORWARD,6}, + {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6}, + {MB_WEIGHT|MB_BACKWARD,6}, {MB_WEIGHT|MB_BACKWARD,6}, + {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6} +}; + +/* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */ +mpeg3_VLCtab_t mpeg3_spBMBtab2[8] = { + {MB_QUANT|MB_INTRA,8}, {MB_QUANT|MB_INTRA,8}, + {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8}, + {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8}, + {MB_WEIGHT|MB_QUANT|MB_BACKWARD|MB_PATTERN,9}, + {MB_CLASS4|MB_QUANT|MB_PATTERN,9}, + {MB_CLASS4,9}, + {MB_CLASS4|MB_PATTERN,9} +}; + +/* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */ +mpeg3_VLCtab_t mpeg3_SNRMBtab[8] = { + {ERROR,0}, + {0,3}, + {MB_QUANT|MB_PATTERN,2}, {MB_QUANT|MB_PATTERN,2}, + {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1} +}; + +/* Table B-10, motion_code, codes 0001 ... 01xx */ +mpeg3_VLCtab_t mpeg3_MVtab0[8] = +{ {ERROR,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1} +}; + +/* Table B-10, motion_code, codes 0000011 ... 000011x */ +mpeg3_VLCtab_t mpeg3_MVtab1[8] = +{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5} +}; + +/* Table B-10, motion_code, codes 0000001100 ... 000001011x */ +mpeg3_VLCtab_t mpeg3_MVtab2[12] = +{ {16,9}, {15,9}, {14,9}, {13,9}, + {12,9}, {11,9}, {10,8}, {10,8}, + {9,8}, {9,8}, {8,8}, {8,8} +}; + +/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */ +mpeg3_VLCtab_t mpeg3_CBPtab0[32] = +{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, + {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, + {62,5}, {2,5}, {61,5}, {1,5}, {56,5}, {52,5}, {44,5}, {28,5}, + {40,5}, {20,5}, {48,5}, {12,5}, {32,4}, {32,4}, {16,4}, {16,4}, + {8,4}, {8,4}, {4,4}, {4,4}, {60,3}, {60,3}, {60,3}, {60,3} +}; + +/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */ +mpeg3_VLCtab_t mpeg3_CBPtab1[64] = +{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, + {58,8}, {54,8}, {46,8}, {30,8}, + {57,8}, {53,8}, {45,8}, {29,8}, {38,8}, {26,8}, {37,8}, {25,8}, + {43,8}, {23,8}, {51,8}, {15,8}, {42,8}, {22,8}, {50,8}, {14,8}, + {41,8}, {21,8}, {49,8}, {13,8}, {35,8}, {19,8}, {11,8}, {7,8}, + {34,7}, {34,7}, {18,7}, {18,7}, {10,7}, {10,7}, {6,7}, {6,7}, + {33,7}, {33,7}, {17,7}, {17,7}, {9,7}, {9,7}, {5,7}, {5,7}, + {63,6}, {63,6}, {63,6}, {63,6}, {3,6}, {3,6}, {3,6}, {3,6}, + {36,6}, {36,6}, {36,6}, {36,6}, {24,6}, {24,6}, {24,6}, {24,6} +}; + +/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */ +mpeg3_VLCtab_t mpeg3_CBPtab2[8] = +{ {ERROR,0}, {0,9}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9} +}; + +/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */ +mpeg3_VLCtab_t mpeg3_MBAtab1[16] = +{ {ERROR,0}, {ERROR,0}, {7,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4}, + {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3} +}; + +/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */ +mpeg3_VLCtab_t mpeg3_MBAtab2[104] = +{ + {33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11}, + {25,11}, {24,11}, {23,11}, {22,11}, {21,10}, {21,10}, {20,10}, {20,10}, + {19,10}, {19,10}, {18,10}, {18,10}, {17,10}, {17,10}, {16,10}, {16,10}, + {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, + {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, + {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, + {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, + {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, + {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, + {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, + {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, + {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, + {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7} +}; + +/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */ +mpeg3_VLCtab_t mpeg3_DClumtab0[32] = +{ {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {ERROR, 0} +}; + +/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */ +mpeg3_VLCtab_t mpeg3_DClumtab1[16] = +{ {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, + {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9} +}; + +/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */ +mpeg3_VLCtab_t mpeg3_DCchromtab0[32] = +{ {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, + {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {ERROR, 0} +}; + +/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */ +mpeg3_VLCtab_t mpeg3_DCchromtab1[32] = +{ {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, + {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, + {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, + {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10} +}; + +/* Table B-14, DCT coefficients table zero, + * codes 0100 ... 1xxx (used for first (DC) coefficient) + */ +mpeg3_DCTtab_t mpeg3_DCTtabfirst[12] = +{ + {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, + {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, + {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1} +}; + +/* Table B-14, DCT coefficients table zero, + * codes 0100 ... 1xxx (used for all other coefficients) + */ +mpeg3_DCTtab_t mpeg3_DCTtabnext[12] = +{ + {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, + {64,0,2}, {64,0,2}, {64,0,2}, {64,0,2}, /* EOB */ + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2} +}; + +/* Table B-14, DCT coefficients table zero, + * codes 000001xx ... 00111xxx + */ +mpeg3_DCTtab_t mpeg3_DCTtab0[60] = +{ + {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ + {2,2,7}, {2,2,7}, {9,1,7}, {9,1,7}, + {0,4,7}, {0,4,7}, {8,1,7}, {8,1,7}, + {7,1,6}, {7,1,6}, {7,1,6}, {7,1,6}, + {6,1,6}, {6,1,6}, {6,1,6}, {6,1,6}, + {1,2,6}, {1,2,6}, {1,2,6}, {1,2,6}, + {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, + {13,1,8}, {0,6,8}, {12,1,8}, {11,1,8}, + {3,2,8}, {1,3,8}, {0,5,8}, {10,1,8}, + {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, + {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, + {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, + {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, + {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, + {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5} +}; + +/* Table B-15, DCT coefficients table one, + * codes 000001xx ... 11111111 +*/ +mpeg3_DCTtab_t mpeg3_DCTtab0a[252] = +{ + {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ + {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7}, + {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7}, + {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6}, + {0,6,6}, {0,6,6}, {0,6,6}, {0,6,6}, + {4,1,6}, {4,1,6}, {4,1,6}, {4,1,6}, + {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, + {1,5,8}, {11,1,8}, {0,11,8}, {0,10,8}, + {13,1,8}, {12,1,8}, {3,2,8}, {1,4,8}, + {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, + {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, + {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, + {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, + {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, + {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, + {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, + {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, + {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, + {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, + {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, + {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, + {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, + {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, + {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */ + {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, + {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, + {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, + {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, + {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, + {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, + {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, + {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, + {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, + {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, + {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, + {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, + {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, + {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, + {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, + {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, + {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, + {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, + {9,1,7}, {9,1,7}, {1,3,7}, {1,3,7}, + {10,1,7}, {10,1,7}, {0,8,7}, {0,8,7}, + {0,9,7}, {0,9,7}, {0,12,8}, {0,13,8}, + {2,3,8}, {4,2,8}, {0,14,8}, {0,15,8} +}; + +/* Table B-14, DCT coefficients table zero, + * codes 0000001000 ... 0000001111 + */ +mpeg3_DCTtab_t mpeg3_DCTtab1[8] = +{ + {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10}, + {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10} +}; + +/* Table B-15, DCT coefficients table one, + * codes 000000100x ... 000000111x + */ +mpeg3_DCTtab_t mpeg3_DCTtab1a[8] = +{ + {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9}, + {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9} +}; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 000000010000 ... 000000011111 + */ +mpeg3_DCTtab_t mpeg3_DCTtab2[16] = +{ + {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12}, + {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12}, + {0,9,12}, {19,1,12}, {18,1,12}, {1,5,12}, + {3,3,12}, {0,8,12}, {6,2,12}, {17,1,12} +}; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 0000000010000 ... 0000000011111 + */ +mpeg3_DCTtab_t mpeg3_DCTtab3[16] = +{ + {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13}, + {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13}, + {0,14,13}, {0,13,13}, {0,12,13}, {26,1,13}, + {25,1,13}, {24,1,13}, {23,1,13}, {22,1,13} +}; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 00000000010000 ... 00000000011111 + */ +mpeg3_DCTtab_t mpeg3_DCTtab4[16] = +{ + {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14}, + {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14}, + {0,23,14}, {0,22,14}, {0,21,14}, {0,20,14}, + {0,19,14}, {0,18,14}, {0,17,14}, {0,16,14} +}; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 000000000010000 ... 000000000011111 + */ +mpeg3_DCTtab_t mpeg3_DCTtab5[16] = +{ + {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15}, + {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15}, + {0,32,15}, {1,14,15}, {1,13,15}, {1,12,15}, + {1,11,15}, {1,10,15}, {1,9,15}, {1,8,15} +}; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 0000000000010000 ... 0000000000011111 + */ +mpeg3_DCTtab_t mpeg3_DCTtab6[16] = +{ + {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16}, + {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16}, + {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16}, + {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16} +}; diff --git a/core/multimedia/opieplayer/libmpeg3/video/vlc.h b/core/multimedia/opieplayer/libmpeg3/video/vlc.h new file mode 100644 index 0000000..727040b --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/vlc.h @@ -0,0 +1,164 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef VLC_H +#define VLC_H + +/* variable length code tables */ + +typedef struct { + char val, len; +} mpeg3_VLCtab_t; + +typedef struct { + char run, level, len; +} mpeg3_DCTtab_t; + +/* Added 03/38/96 by Alex de Jong : avoid IRIX GNU warning */ +#ifdef ERROR +#undef ERROR +#define ERROR 99 +#endif + +/* Table B-3, mb_type in P-pictures, codes 001..1xx */ +extern mpeg3_VLCtab_t mpeg3_PMBtab0[8]; + +/* Table B-3, mb_type in P-pictures, codes 000001..00011x */ +extern mpeg3_VLCtab_t mpeg3_PMBtab1[8]; + +/* Table B-4, mb_type in B-pictures, codes 0010..11xx */ +extern mpeg3_VLCtab_t mpeg3_BMBtab0[16]; + +/* Table B-4, mb_type in B-pictures, codes 000001..00011x */ +extern mpeg3_VLCtab_t mpeg3_BMBtab1[8]; + +/* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */ +extern mpeg3_VLCtab_t mpeg3_spIMBtab[16]; + +/* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */ +extern mpeg3_VLCtab_t mpeg3_spPMBtab0[16]; + +/* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */ +extern mpeg3_VLCtab_t mpeg3_spPMBtab1[16]; + +/* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */ +extern mpeg3_VLCtab_t mpeg3_spBMBtab0[14]; + +/* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */ +extern mpeg3_VLCtab_t mpeg3_spBMBtab1[12]; + +/* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */ +extern mpeg3_VLCtab_t mpeg3_spBMBtab2[8]; + +/* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */ +extern mpeg3_VLCtab_t mpeg3_SNRMBtab[8]; + +/* Table B-10, motion_code, codes 0001 ... 01xx */ +extern mpeg3_VLCtab_t mpeg3_MVtab0[8]; + +/* Table B-10, motion_code, codes 0000011 ... 000011x */ +extern mpeg3_VLCtab_t mpeg3_MVtab1[8]; + +/* Table B-10, motion_code, codes 0000001100 ... 000001011x */ +extern mpeg3_VLCtab_t mpeg3_MVtab2[12]; + +/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */ +extern mpeg3_VLCtab_t mpeg3_CBPtab0[32]; + +/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */ +extern mpeg3_VLCtab_t mpeg3_CBPtab1[64]; + +/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */ +extern mpeg3_VLCtab_t mpeg3_CBPtab2[8]; + +/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */ +extern mpeg3_VLCtab_t mpeg3_MBAtab1[16]; + +/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */ +extern mpeg3_VLCtab_t mpeg3_MBAtab2[104]; + +/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */ +extern mpeg3_VLCtab_t mpeg3_DClumtab0[32]; + +/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */ +extern mpeg3_VLCtab_t mpeg3_DClumtab1[16]; + +/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */ +extern mpeg3_VLCtab_t mpeg3_DCchromtab0[32]; + +/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */ +extern mpeg3_VLCtab_t mpeg3_DCchromtab1[32]; + +/* Table B-14, DCT coefficients table zero, + * codes 0100 ... 1xxx (used for first (DC) coefficient) + */ +extern mpeg3_DCTtab_t mpeg3_DCTtabfirst[12]; + +/* Table B-14, DCT coefficients table zero, + * codes 0100 ... 1xxx (used for all other coefficients) + */ +extern mpeg3_DCTtab_t mpeg3_DCTtabnext[12]; + +/* Table B-14, DCT coefficients table zero, + * codes 000001xx ... 00111xxx + */ +extern mpeg3_DCTtab_t mpeg3_DCTtab0[60]; + +/* Table B-15, DCT coefficients table one, + * codes 000001xx ... 11111111 +*/ +extern mpeg3_DCTtab_t mpeg3_DCTtab0a[252]; + +/* Table B-14, DCT coefficients table zero, + * codes 0000001000 ... 0000001111 + */ +extern mpeg3_DCTtab_t mpeg3_DCTtab1[8]; + +/* Table B-15, DCT coefficients table one, + * codes 000000100x ... 000000111x + */ +extern mpeg3_DCTtab_t mpeg3_DCTtab1a[8]; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 000000010000 ... 000000011111 + */ +extern mpeg3_DCTtab_t mpeg3_DCTtab2[16]; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 0000000010000 ... 0000000011111 + */ +extern mpeg3_DCTtab_t mpeg3_DCTtab3[16]; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 00000000010000 ... 00000000011111 + */ +extern mpeg3_DCTtab_t mpeg3_DCTtab4[16]; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 000000000010000 ... 000000000011111 + */ +extern mpeg3_DCTtab_t mpeg3_DCTtab5[16]; + +/* Table B-14/15, DCT coefficients table zero / one, + * codes 0000000000010000 ... 0000000000011111 + */ +extern mpeg3_DCTtab_t mpeg3_DCTtab6[16]; + + +#endif diff --git a/core/multimedia/opieplayer/libmpeg3/video/worksheet.c b/core/multimedia/opieplayer/libmpeg3/video/worksheet.c new file mode 100644 index 0000000..c5a0553 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/worksheet.c @@ -0,0 +1,30 @@ +#include +#include +#include + + +static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004000400040; + +inline void mpeg3_601_mmx(unsigned long y, + unsigned long *output) +{ +asm(" +/* Output will be 0x00rrggbb */ + movd (%0), %%mm0; /* Load y 0x00000000000000yy */ +/* pmullw mpeg3_MMX_601_Y_COEF, %%mm0; // Scale y 0x00000000000000yy */ + psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */ + movd %%mm0, (%1); /* Store output */ + " +: +: "r" (&y), "r" (output)); +} + + +int main(int argc, char *argv[]) +{ + unsigned char output[1024]; + + memset(output, 0, 1024); + mpeg3_601_mmx(1, (unsigned long*)output); + printf("%02x%02x\n", *(unsigned char*)&output[1], *(unsigned char*)&output[0]); +} diff --git a/core/multimedia/opieplayer/loopcontrol.cpp b/core/multimedia/opieplayer/loopcontrol.cpp new file mode 100644 index 0000000..93a6e3f --- a/dev/null +++ b/core/multimedia/opieplayer/loopcontrol.cpp @@ -0,0 +1,464 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#ifdef Q_WS_QWS +#include +#endif +#include +#include +#include +#include +#include +#include +#include "loopcontrol.h" +#include "videowidget.h" +#include "audiodevice.h" +#include "mediaplayerplugininterface.h" +#include "mediaplayerstate.h" + + +extern VideoWidget *videoUI; // now only needed to tell it to play a frame +extern MediaPlayerState *mediaPlayerState; + + +//#define DecodeLoopDebug(x) qDebug x +#define DecodeLoopDebug(x) + + +static char *audioBuffer = NULL; +static AudioDevice *audioDevice = NULL; +static bool disabledSuspendScreenSaver = FALSE; +static bool previousSuspendMode = FALSE; + + +pthread_t audio_tid; +pthread_attr_t audio_attr; +bool threadOkToGo = FALSE; + + +class Mutex { +public: + Mutex() { + pthread_mutexattr_t attr; + pthread_mutexattr_init( &attr ); + pthread_mutex_init( &mutex, &attr ); + pthread_mutexattr_destroy( &attr ); + } + + ~Mutex() { + pthread_mutex_destroy( &mutex ); + } + + void lock() { + pthread_mutex_lock( &mutex ); + } + + void unlock() { + pthread_mutex_unlock( &mutex ); + } +private: + pthread_mutex_t mutex; +}; + + +void *startAudioThread( void *ptr ) { + LoopControl *mpegView = (LoopControl *)ptr; + while ( TRUE ) { + if ( threadOkToGo && mpegView->moreAudio ) + mpegView->startAudio(); + else + usleep( 10000 ); // Semi-buzy-wait till we are playing again + } + return 0; +} + + +Mutex *audioMutex; + + +LoopControl::LoopControl( QObject *parent, const char *name ) + : QObject( parent, name ) { + isMuted = FALSE; + connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) ); + + audioMutex = new Mutex; + + pthread_attr_init(&audio_attr); +#define USE_REALTIME_AUDIO_THREAD +#ifdef USE_REALTIME_AUDIO_THREAD + // Attempt to set it to real-time round robin + if ( pthread_attr_setschedpolicy( &audio_attr, SCHED_RR ) == 0 ) { + sched_param params; + params.sched_priority = 50; + pthread_attr_setschedparam(&audio_attr,¶ms); + } else { + qDebug( "Error setting up a realtime thread, reverting to using a normal thread." ); + pthread_attr_destroy(&audio_attr); + pthread_attr_init(&audio_attr); + } +#endif + pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this); +} + + +LoopControl::~LoopControl() { + stop(); +} + + +static long prev_frame = 0; +static int currentSample = 0; + + +void LoopControl::timerEvent( QTimerEvent *te ) { + + if ( te->timerId() == videoId ) + startVideo(); + + if ( te->timerId() == sliderId ) { + if ( hasAudioChannel && !hasVideoChannel && moreAudio ) { + mediaPlayerState->updatePosition( audioSampleCounter ); + } else if ( hasVideoChannel && moreVideo ) { + mediaPlayerState->updatePosition( current_frame ); + } + } + + if ( !moreVideo && !moreAudio ) { + mediaPlayerState->setPlaying( FALSE ); + mediaPlayerState->setNext(); + } +} + + +void LoopControl::setPosition( long pos ) { + audioMutex->lock(); + + if ( hasVideoChannel && hasAudioChannel ) { + playtime.restart(); + playtime = playtime.addMSecs( long((double)-pos * 1000.0 / framerate) ); + current_frame = pos + 1; + mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); + prev_frame = current_frame - 1; + currentSample = (int)( (double)current_frame * freq / framerate ); + mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream ); + audioSampleCounter = currentSample - 1; + } else if ( hasVideoChannel ) { + playtime.restart(); + playtime = playtime.addMSecs( long((double)-pos * 1000.0 / framerate) ); + current_frame = pos + 1; + mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); + prev_frame = current_frame - 1; + } else if ( hasAudioChannel ) { + playtime.restart(); + playtime = playtime.addMSecs( long((double)-pos * 1000.0 / freq) ); + currentSample = pos + 1; + mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream ); + audioSampleCounter = currentSample - 1; + } + + audioMutex->unlock(); +} + + +void LoopControl::startVideo() { + + if ( moreVideo ) { + + if ( mediaPlayerState->curDecoder() ) { + + if ( hasAudioChannel && !isMuted ) { + + current_frame = long( playtime.elapsed() * framerate / 1000 ); + + if ( prev_frame != -1 && current_frame <= prev_frame ) + return; + + } else { + // Don't skip + current_frame++; + } + + if ( prev_frame == -1 || current_frame > prev_frame ) { + if ( current_frame > prev_frame + 1 ) { + mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); + } + moreVideo = videoUI->playVideo(); + prev_frame = current_frame; + } + + } else { + + moreVideo = FALSE; + killTimer( videoId ); + + } + + } +} + + +void LoopControl::startAudio() { + + audioMutex->lock(); + + if ( moreAudio ) { + + if ( !isMuted && mediaPlayerState->curDecoder() ) { + + currentSample = audioSampleCounter + 1; + + if ( currentSample != audioSampleCounter + 1 ) + qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter); + + long samplesRead = 0; + mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, 1024, samplesRead, stream ); + long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000; + long sampleWaitTime = currentSample - sampleWeShouldBeAt; + + if ( ( sampleWaitTime > 2000 ) && ( sampleWaitTime < 20000 ) ) { + usleep( (long)((double)sampleWaitTime * 1000000.0 / freq) ); + } else if ( sampleWaitTime <= -5000 ) { + qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt ); + //mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream ); + currentSample = sampleWeShouldBeAt; + } + + audioDevice->write( audioBuffer, samplesRead * 2 * channels ); + audioSampleCounter = currentSample + samplesRead - 1; + + moreAudio = audioSampleCounter <= total_audio_samples; + + } else { + + moreAudio = FALSE; + + } + + } + + audioMutex->unlock(); +} + + +void LoopControl::killTimers() { + + audioMutex->lock(); + + if ( hasVideoChannel ) + killTimer( videoId ); + killTimer( sliderId ); + threadOkToGo = FALSE; + + audioMutex->unlock(); +} + + +void LoopControl::startTimers() { + + audioMutex->lock(); + + moreVideo = FALSE; + moreAudio = FALSE; + + if ( hasVideoChannel ) { + moreVideo = TRUE; + int mSecsBetweenFrames = (int)(100 / framerate); // 10% of the real value + videoId = startTimer( mSecsBetweenFrames ); + } + + if ( hasAudioChannel ) { + moreAudio = TRUE; + threadOkToGo = TRUE; + } + + sliderId = startTimer( 300 ); // update slider every 1/3 second + + audioMutex->unlock(); +} + + +void LoopControl::setPaused( bool pause ) { + + if ( !mediaPlayerState->curDecoder() || !mediaPlayerState->curDecoder()->isOpen() ) + return; + + if ( pause ) { + killTimers(); + } else { + // Force an update of the position + mediaPlayerState->setPosition( mediaPlayerState->position() + 1 ); + mediaPlayerState->setPosition( mediaPlayerState->position() - 1 ); + // Just like we never stopped + startTimers(); + } +} + + +void LoopControl::stop( bool willPlayAgainShortly ) { + +#if defined(Q_WS_QWS) && !defined(QT_NO_COP) + if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) { + disabledSuspendScreenSaver = FALSE; + // Re-enable the suspend mode + QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; + } +#endif + + if ( mediaPlayerState->curDecoder() && mediaPlayerState->curDecoder()->isOpen() ) { + + killTimers(); + + audioMutex->lock(); + + mediaPlayerState->curDecoder()->close(); + + if ( audioDevice ) { + delete audioDevice; + delete audioBuffer; + audioDevice = 0; + audioBuffer = 0; + } + + audioMutex->unlock(); + + } +} + + +bool LoopControl::init( const QString& filename ) { + stop(); + + audioMutex->lock(); + + fileName = filename; + stream = 0; // only play stream 0 for now + current_frame = total_video_frames = total_audio_samples = 0; + + qDebug( "Using the %s decoder", mediaPlayerState->curDecoder()->pluginName() ); + + // ### Hack to use libmpeg3plugin to get the number of audio samples if we are using the libmad plugin + if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) { + if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename ) ) { + total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 ); + mediaPlayerState->libMpeg3Decoder()->close(); + } + } + + if ( !mediaPlayerState->curDecoder()|| !mediaPlayerState->curDecoder()->open( filename ) ) { + audioMutex->unlock(); + return FALSE; + } + + hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0; + hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0; + + if ( hasAudioChannel ) { + int astream = 0; + + channels = mediaPlayerState->curDecoder()->audioChannels( astream ); + DecodeLoopDebug(( "channels = %d\n", channels )); + + if ( !total_audio_samples ) + total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream ); + + total_audio_samples += 1000; + + mediaPlayerState->setLength( total_audio_samples ); + + freq = mediaPlayerState->curDecoder()->audioFrequency( astream ); + DecodeLoopDebug(( "frequency = %d\n", freq )); + + audioSampleCounter = 0; + + static const int bytes_per_sample = 2; //16 bit + + audioDevice = new AudioDevice( freq, channels, bytes_per_sample ); + audioBuffer = new char[ audioDevice->bufferSize() ]; + channels = audioDevice->channels(); + + //### must check which frequency is actually used. + static const int size = 1; + short int buf[size]; + long samplesRead = 0; + mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream ); + } + + if ( hasVideoChannel ) { + total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream ); + + mediaPlayerState->setLength( total_video_frames ); + + framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream ); + DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames )); + + if ( framerate <= 1.0 ) { + DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" )); + framerate = 25; + } + + if ( total_video_frames == 1 ) { + DecodeLoopDebug(( "Cannot seek to frame" )); + } + + } + + current_frame = 0; + prev_frame = -1; + + connect( mediaPlayerState, SIGNAL( positionChanged( long ) ), this, SLOT( setPosition( long ) ) ); + connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( setPaused( bool ) ) ); + + audioMutex->unlock(); + + return TRUE; +} + + +void LoopControl::play() { + +#if defined(Q_WS_QWS) && !defined(QT_NO_COP) + if ( !disabledSuspendScreenSaver || previousSuspendMode != hasVideoChannel ) { + disabledSuspendScreenSaver = TRUE; + previousSuspendMode = hasVideoChannel; + // Stop the screen from blanking and power saving state + QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) + << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend ); + } +#endif + + playtime.start(); + startTimers(); +} + + +void LoopControl::setMute( bool on ) { + if ( on != isMuted ) { + isMuted = on; + if ( !on ) { + // Force an update of the position + mediaPlayerState->setPosition( mediaPlayerState->position() + 1 ); + mediaPlayerState->setPosition( mediaPlayerState->position() - 1 ); + // Resume playing audio + moreAudio = TRUE; + } + } +} + + diff --git a/core/multimedia/opieplayer/loopcontrol.h b/core/multimedia/opieplayer/loopcontrol.h new file mode 100644 index 0000000..967ee25 --- a/dev/null +++ b/core/multimedia/opieplayer/loopcontrol.h @@ -0,0 +1,88 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEGVIEW_H +#define MPEGVIEW_H + + +#include +#include + + +class LoopControl : public QObject { + Q_OBJECT +public: + LoopControl( QObject *parent, const char *name ); + ~LoopControl(); + + bool init( const QString& filename ); + + bool hasVideo() const { return hasVideoChannel; } + bool hasAudio() const { return hasAudioChannel; } + + long totalPlaytime() { return (long)(hasVideoChannel ? total_video_frames / framerate : total_audio_samples / freq); } + + // These are public to run them from global functions needed to start threads + // Otherwise they would be private + void startAudio(); + void startVideo(); + bool moreAudio; + bool moreVideo; +public slots: + void play(); + void stop( bool willPlayAgainShortly = FALSE ); + + void setMute( bool ); + void setPaused( bool ); + void setPosition( long ); + +signals: + void positionChanged( long, long ); + +protected: + void timerEvent(QTimerEvent*); + +private: + void startTimers(); + void killTimers(); + + QTime playtime; + int videoId; + int sliderId; + + int audioSampleCounter; + long current_frame; + long total_video_frames; + long total_audio_samples; + + float framerate; + int freq; + int stream; + int framecount; + int channels; + + bool hasVideoChannel; + bool hasAudioChannel; + bool isMuted; + QString fileName; +}; + + +#endif + diff --git a/core/multimedia/opieplayer/loopcontrol_threaded.cpp b/core/multimedia/opieplayer/loopcontrol_threaded.cpp new file mode 100644 index 0000000..2ec4a48 --- a/dev/null +++ b/core/multimedia/opieplayer/loopcontrol_threaded.cpp @@ -0,0 +1,626 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#define _REENTRANT + +#include +#include +#include +#ifdef Q_WS_QWS +#include +#endif +#include +#include +#include +#include +#include +#include +#include "loopcontrol.h" +#include "audiodevice.h" +#include "videowidget.h" +#include "audiowidget.h" +#include "mediaplayerplugininterface.h" +#include "mediaplayerstate.h" + + +#if defined(QT_QWS_CUSTOM) || defined(QT_QWS_IPAQ) +#define USE_REALTIME_AUDIO_THREAD +#endif + + +extern VideoWidget *videoUI; // now only needed to tell it to play a frame +extern MediaPlayerState *mediaPlayerState; + + +#define DecodeLoopDebug(x) qDebug x +//#define DecodeLoopDebug(x) + + +static char *audioBuffer = NULL; +static AudioDevice *audioDevice = NULL; +static bool disabledSuspendScreenSaver = FALSE; + + +pthread_t video_tid; +pthread_attr_t video_attr; +pthread_t audio_tid; +pthread_attr_t audio_attr; + + +bool emitPlayFinished = FALSE; +bool emitChangePos = FALSE; + + +class Mutex { +public: + Mutex() { + pthread_mutexattr_t attr; + pthread_mutexattr_init( &attr ); + pthread_mutex_init( &mutex, &attr ); + pthread_mutexattr_destroy( &attr ); + } + + ~Mutex() { + pthread_mutex_destroy( &mutex ); + } + + void lock() { + pthread_mutex_lock( &mutex ); + } + + void unlock() { + pthread_mutex_unlock( &mutex ); + } +/* + bool locked() { + switch ( pthread_mutex_trylock( &mutex ) ) { + case EBUSY: + return TRUE; + case 0: + pthread_mutex_unlock( &mutex ); + default: + return FALSE; + } + } +*/ +private: + pthread_mutex_t mutex; +}; + + +class currentFrameObj { +public: + currentFrameObj() : value( 0 ) { } + void set( long f ) { + mutex.lock(); + value = f; + mediaPlayerState->curDecoder()->videoSetFrame( f, 0 ); + mutex.unlock(); + } + long get() { + return value; + } +private: + long value; + Mutex mutex; +}; + + +Mutex *videoMutex; +Mutex *audioMutex; +Mutex *globalMutex; + + +clock_t begin; + + +LoopControl::LoopControl( QObject *parent, const char *name ) + : QObject( parent, name ) { + isMuted = FALSE; + connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) ); + timerid = startTimer( 200 ); + videoMutex = new Mutex; + audioMutex = new Mutex; + globalMutex = new Mutex; + //begin = clock(); +} + + +LoopControl::~LoopControl() { + stop(); + killTimer( timerid ); +} + + +static bool sendingNewPos = FALSE; +static long prev_frame = 0; +static int currentSample = 0; + + +void LoopControl::timerEvent( QTimerEvent* ) { + // We need to emit playFinished from the main thread, not one of the + // decoding threads else we'll have all kinds of yucky things happen (reentrance). + // playFinished will eventually call stop() which stops these threads. + if ( emitPlayFinished ) { + emitPlayFinished = FALSE; + mediaPlayerState->setPlaying( FALSE ); + } + + if ( emitChangePos ) { + + emitChangePos = FALSE; + + if ( hasVideoChannel && hasAudioChannel ) { + sendingNewPos = TRUE; + mediaPlayerState->setPosition( current_frame ); + } else if ( hasVideoChannel ) { + sendingNewPos = TRUE; + mediaPlayerState->setPosition( current_frame ); + } else if ( hasAudioChannel ) { + sendingNewPos = TRUE; + mediaPlayerState->setPosition( audioSampleCounter ); + } + + } +} + + + + +void LoopControl::setPosition( long pos ) { + if ( sendingNewPos ) { + sendingNewPos = FALSE; + return; + } + + if ( hasVideoChannel && hasAudioChannel ) { + videoMutex->lock(); + audioMutex->lock(); +qDebug("setting position"); + playtime.restart(); + playtime = playtime.addMSecs( -pos * 1000 / framerate ); + //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate; + current_frame = pos + 1; + mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); + prev_frame = current_frame - 1; + currentSample = (int)( current_frame * freq / framerate ); + mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream ); + audioSampleCounter = currentSample - 1; + audioMutex->unlock(); + videoMutex->unlock(); + } else if ( hasVideoChannel ) { + videoMutex->lock(); + playtime.restart(); + playtime = playtime.addMSecs( -pos * 1000 / framerate ); + //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate; + current_frame = pos + 1; + mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); + videoMutex->unlock(); + prev_frame = current_frame - 1; + } else if ( hasAudioChannel ) { + audioMutex->lock(); + playtime.restart(); + playtime = playtime.addMSecs( -pos * 1000 / freq ); + //begin = clock() - (double)pos * CLOCKS_PER_SEC / freq; + currentSample = pos + 1; // (int)( current_frame * freq / framerate ); + mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream ); + audioSampleCounter = currentSample - 1; + audioMutex->unlock(); + } +} + + +void *startVideoThread( void *ptr ) { + LoopControl *mpegView = (LoopControl *)ptr; + mpegView->startVideo(); + return 0; +} + +void *startAudioThread( void *ptr ) { + LoopControl *mpegView = (LoopControl *)ptr; + mpegView->startAudio(); + return 0; +} + +void LoopControl::startVideo() { + moreVideo = TRUE; + + while ( moreVideo ) { + + if ( mediaPlayerState->curDecoder() && hasVideoChannel ) { + + if ( hasAudioChannel && !isMuted ) { + + bool done = FALSE; + + do { + + +/* + videoMutex->lock(); + current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 ); + //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC; + + // Sync to Audio +// current_frame = (long)((double)(audioSampleCounter - 1000) * framerate / (double)freq); + + long mSecsToNextFrame = 0; + + if ( current_frame == prev_frame ) { + int nf = current_frame + 1; + if ( nf > 0 && nf != total_video_frames ) + // mSecsToNextFrame = long(double(nf * CLOCKS_PER_SEC) / framerate) - ( clock() - begin ); + mSecsToNextFrame = long(double(nf * 1000) / framerate) - ( playtime.elapsed() ); + } + videoMutex->unlock(); + + if ( mSecsToNextFrame ) { + usleep( mSecsToNextFrame ); // wait a bit + + videoMutex->lock(); + // This should now be the next frame + current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 ); + //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC; + videoMutex->unlock(); + } + + videoMutex->lock(); + done = current_frame >= prev_frame; + videoMutex->unlock(); +*/ + videoMutex->lock(); + current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 ); + done = current_frame >= prev_frame; + videoMutex->unlock(); + if ( !done ) + usleep( 1000 ); // wait a bit + + } while ( !done ); + +// qDebug("elapsed: %i %i (%f)", int( playtime.elapsed() ), current_frame, framerate ); + + } else { + videoMutex->lock(); + current_frame++; + videoMutex->unlock(); + } + + videoMutex->lock(); + bool check = current_frame && current_frame > prev_frame; + videoMutex->unlock(); + + if ( check ) { + videoMutex->lock(); + if ( current_frame > prev_frame + 1 ) { + qDebug("skipped a frame"); + mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); + } + prev_frame = current_frame; + if ( moreVideo = videoUI->playVideo() ) + emitChangePos = TRUE; + videoMutex->unlock(); + } + + } else + moreVideo = FALSE; + + } + + if ( !moreVideo && !moreAudio ) + emitPlayFinished = TRUE; + + pthread_exit(NULL); +} + +void LoopControl::startAudio() { + moreAudio = TRUE; + + while ( moreAudio ) { + + if ( !isMuted && mediaPlayerState->curDecoder() && hasAudioChannel ) { + + audioMutex->lock(); + currentSample = mediaPlayerState->curDecoder()->audioGetSample( stream ); + + if ( currentSample == 0 ) + currentSample = audioSampleCounter + 1; + + if ( currentSample != audioSampleCounter + 1 ) + qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter); + audioMutex->unlock(); + +/* + int sampleWeShouldBeAt = int( playtime.elapsed() ) * freq / 1000; + + if ( sampleWeShouldBeAt - currentSample > 20000 ) { + mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream ); + currentSample = sampleWeShouldBeAt; + } +*/ + long samplesRead = 0; + + const long samples = 1024; + + moreAudio = !mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, samples, samplesRead, stream ); + + audioMutex->lock(); + long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000; + //long sampleWeShouldBeAt = long( clock() - begin ) * (double) freq / CLOCKS_PER_SEC; + long sampleWaitTime = currentSample - sampleWeShouldBeAt; + audioMutex->unlock(); + + if ( sampleWaitTime >= 0 && sampleWaitTime <= 2000 ) { + //qDebug("sampleWaitTime: %i", sampleWaitTime); + usleep( ( sampleWaitTime * 1000000 ) / ( freq ) ); + } else { + audioMutex->lock(); + if ( sampleWaitTime <= -2000 ) { + qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt ); + mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream ); + currentSample = sampleWeShouldBeAt; + } + audioMutex->unlock(); + } + + audioDevice->write( audioBuffer, samplesRead * 2 * channels ); + + audioMutex->lock(); +// audioSampleCounter += samplesRead; + audioSampleCounter = currentSample + samplesRead - 1; + audioMutex->unlock(); + + if ( !hasVideoChannel ) + emitChangePos = TRUE; + + //qDebug("currentSample: %i audioSampleCounter: %i total_audio_samples: %i", currentSample, audioSampleCounter, total_audio_samples); +// qDebug("current: %i counter: %i total: %i", currentSample, audioSampleCounter, (int)total_audio_samples); + moreAudio = audioSampleCounter <= total_audio_samples; + + } else { + + if ( mediaPlayerState->curDecoder() && hasAudioChannel ) + usleep( 100000 ); // Check every 1/10 sec to see if mute is off + else + moreAudio = FALSE; + + } + } + + qDebug( "End of file" ); + + if ( !moreVideo && !moreAudio ) + emitPlayFinished = TRUE; + + pthread_exit(NULL); +} + +void LoopControl::killTimers() { + if ( hasVideoChannel ) { + if ( pthread_self() != video_tid ) { + if ( pthread_cancel(video_tid) == 0 ) { + void *thread_result = 0; + if ( pthread_join(video_tid,&thread_result) != 0 ) + qDebug("thread join error 1"); + pthread_attr_destroy(&video_attr); + } + } + } + if ( hasAudioChannel ) { + if ( pthread_self() != audio_tid ) { + if ( pthread_cancel(audio_tid) == 0 ) { + void *thread_result = 0; + if ( pthread_join(audio_tid,&thread_result) != 0 ) + qDebug("thread join error 2"); + pthread_attr_destroy(&audio_attr); + } + } + } +} + +void LoopControl::startTimers() { + moreVideo = FALSE; + moreAudio = FALSE; + + if ( hasVideoChannel ) { + moreVideo = TRUE; + pthread_attr_init(&video_attr); + pthread_create(&video_tid, &video_attr, (void * (*)(void *))startVideoThread, this); + } + + if ( hasAudioChannel ) { + moreAudio = TRUE; + pthread_attr_init(&audio_attr); +#ifdef USE_REALTIME_AUDIO_THREAD + pthread_attr_setschedpolicy(&audio_attr,SCHED_RR); // Real-time round robin + //qDebug("min: %i, max: %i", sched_get_priority_min( SCHED_RR ), sched_get_priority_max( SCHED_RR ) ); + sched_param params; + params.sched_priority = 50; + pthread_attr_setschedparam(&audio_attr,¶ms); +#endif + pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this); + } +} + + + + +void LoopControl::setPaused( bool pause ) { + static int whenPaused = 0; + + if ( !mediaPlayerState->curDecoder() || !mediaPlayerState->curDecoder()->isOpen() ) + return; + + if ( pause ) { + // Remember where we are + whenPaused = playtime.elapsed(); + killTimers(); + } else { + // Just like we never stopped + playtime.restart(); + playtime = playtime.addMSecs( -whenPaused ); + whenPaused = 0; + startTimers(); + } +} + + +void LoopControl::stop( bool willPlayAgainShortly ) { + +#if defined(Q_WS_QWS) && !defined(QT_NO_COP) + if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) { + disabledSuspendScreenSaver = FALSE; + // Re-enable the suspend mode + QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; + } +#endif + + if ( mediaPlayerState->curDecoder() && mediaPlayerState->curDecoder()->isOpen() ) { + + killTimers(); + + mediaPlayerState->curDecoder()->close(); + + if ( audioDevice ) { + delete audioDevice; + delete audioBuffer; + audioDevice = 0; + audioBuffer = 0; + } + + } +} + + +bool LoopControl::init( const QString& filename ) { + stop(); + fileName = filename; + stream = 0; // only play stream 0 for now + current_frame = total_video_frames = total_audio_samples = 0; + + qDebug( "Using the %s decoder", mediaPlayerState->curDecoder()->pluginName() ); + + // ### Hack to use libmpeg3plugin to get the number of audio samples if we are using the libmad plugin + if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) { + if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename ) ) { + total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 ); + mediaPlayerState->libMpeg3Decoder()->close(); + } + } + + if ( !mediaPlayerState->curDecoder()|| !mediaPlayerState->curDecoder()->open( filename ) ) + return FALSE; + + hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0; + hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0; + + if ( hasAudioChannel ) { + int astream = 0; + + channels = mediaPlayerState->curDecoder()->audioChannels( astream ); + DecodeLoopDebug(( "channels = %d\n", channels )); + + if ( !total_audio_samples ) + total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream ); + + mediaPlayerState->setLength( total_audio_samples ); + + freq = mediaPlayerState->curDecoder()->audioFrequency( astream ); + DecodeLoopDebug(( "frequency = %d\n", freq )); + + audioSampleCounter = 0; + + static const int bytes_per_sample = 2; //16 bit + + audioDevice = new AudioDevice( freq, channels, bytes_per_sample ); + audioBuffer = new char[ audioDevice->bufferSize() ]; + channels = audioDevice->channels(); + + //### must check which frequency is actually used. + static const int size = 1; + short int buf[size]; + long samplesRead = 0; + mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream ); + } + + if ( hasVideoChannel ) { + total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream ); + + mediaPlayerState->setLength( total_video_frames ); + + framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream ); + DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames )); + + if ( framerate <= 1.0 ) { + DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" )); + framerate = 25; + } + + if ( total_video_frames == 1 ) { + DecodeLoopDebug(( "Cannot seek to frame" )); + } + + } + + videoMutex->lock(); + current_frame = 0; + prev_frame = -1; + videoMutex->unlock(); + + connect( mediaPlayerState, SIGNAL( positionChanged( long ) ), this, SLOT( setPosition( long ) ) ); + connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( setPaused( bool ) ) ); + + //setBackgroundColor( black ); + return TRUE; +} + + +void LoopControl::play() { + +#if defined(Q_WS_QWS) && !defined(QT_NO_COP) + if ( !disabledSuspendScreenSaver ) { + disabledSuspendScreenSaver = TRUE; + // Stop the screen from blanking and power saving state + QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) + << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend ); + } +#endif + + //begin = clock(); + playtime.start(); + startTimers(); + //updateGeometry(); +} + + +void LoopControl::setMute( bool on ) { + if ( isMuted != on ) { + isMuted = on; + if ( isMuted ) { + } else { + int frame = current_frame; // mediaPlayerState->curDecoder()->videoGetFrame( stream ); + playtime.restart(); + playtime = playtime.addMSecs( -frame * 1000 / framerate ); + //begin = clock() - (double)frame * CLOCKS_PER_SEC / framerate; + mediaPlayerState->curDecoder()->audioSetSample( frame*freq/framerate, stream ); + } + } +} + + diff --git a/core/multimedia/opieplayer/loopcontrol_threaded.h b/core/multimedia/opieplayer/loopcontrol_threaded.h new file mode 100644 index 0000000..9a009d1 --- a/dev/null +++ b/core/multimedia/opieplayer/loopcontrol_threaded.h @@ -0,0 +1,89 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MPEGVIEW_H +#define MPEGVIEW_H + + +#include +#include + + +class LoopControl : public QObject { + Q_OBJECT +public: + LoopControl( QObject *parent, const char *name ); + ~LoopControl(); + + bool init( const QString& filename ); + + bool hasVideo() const { return hasVideoChannel; } + bool hasAudio() const { return hasAudioChannel; } + + long totalPlaytime() { return (long)(hasVideoChannel ? total_video_frames / framerate : total_audio_samples / freq); } + + // These are public to run them from global functions needed to start threads + // Otherwise they would be private + void startAudio(); + void startVideo(); +public slots: + void play(); + void stop( bool willPlayAgainShortly = FALSE ); + + void setMute( bool ); + void setPaused( bool ); + void setPosition( long ); + +signals: + void positionChanged( long, long ); + void playFinished(); + +protected: + void timerEvent(QTimerEvent*); + +private: + void startTimers(); + void killTimers(); + + + QTime playtime; + int timerid; + int audioSampleCounter; + long current_frame; + long total_video_frames; + long total_audio_samples; + + float framerate; + int freq; + int stream; + int framecount; + int channels; + + bool moreAudio; + bool moreVideo; + + bool hasVideoChannel; + bool hasAudioChannel; + bool isMuted; + QString fileName; +}; + + +#endif + diff --git a/core/multimedia/opieplayer/main.cpp b/core/multimedia/opieplayer/main.cpp new file mode 100644 index 0000000..5246e40 --- a/dev/null +++ b/core/multimedia/opieplayer/main.cpp @@ -0,0 +1,57 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include "mediaplayerstate.h" +#include "playlistwidget.h" +#include "audiowidget.h" +#include "videowidget.h" +#include "loopcontrol.h" +#include "mediaplayer.h" + + +MediaPlayerState *mediaPlayerState; +PlayListWidget *playList; +AudioWidget *audioUI; +VideoWidget *videoUI; +LoopControl *loopControl; + + +int main(int argc, char **argv) { + QPEApplication a(argc,argv); + + MediaPlayerState st( 0, "mediaPlayerState" ); + mediaPlayerState = &st; + PlayListWidget pl( 0, "playList" ); + playList = &pl; + AudioWidget aw( 0, "audioUI" ); + audioUI = &aw; + VideoWidget vw( 0, "videoUI" ); + videoUI = &vw; + LoopControl lc( 0, "loopControl" ); + loopControl = &lc; + MediaPlayer mp( 0, "mediaPlayer" ); + + pl.setCaption( MediaPlayer::tr("Media Player") ); + a.showMainDocumentWidget(&pl); + + return a.exec(); +} + + diff --git a/core/multimedia/opieplayer/mediaplayer.cpp b/core/multimedia/opieplayer/mediaplayer.cpp new file mode 100644 index 0000000..3d8f76c --- a/dev/null +++ b/core/multimedia/opieplayer/mediaplayer.cpp @@ -0,0 +1,182 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "mediaplayer.h" +#include "playlistwidget.h" +#include "audiowidget.h" +#include "loopcontrol.h" +#include "audiodevice.h" + +#include "mediaplayerstate.h" + + +extern AudioWidget *audioUI; +extern PlayListWidget *playList; +extern LoopControl *loopControl; +extern MediaPlayerState *mediaPlayerState; + + +MediaPlayer::MediaPlayer( QObject *parent, const char *name ) + : QObject( parent, name ), volumeDirection( 0 ), currentFile( NULL ) { + + connect( mediaPlayerState, SIGNAL( playingToggled( bool ) ), this, SLOT( setPlaying( bool ) ) ); + connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( pauseCheck( bool ) ) ); + connect( mediaPlayerState, SIGNAL( next() ), this, SLOT( next() ) ); + connect( mediaPlayerState, SIGNAL( prev() ), this, SLOT( prev() ) ); + + connect( audioUI, SIGNAL( moreClicked() ), this, SLOT( startIncreasingVolume() ) ); + connect( audioUI, SIGNAL( lessClicked() ), this, SLOT( startDecreasingVolume() ) ); + connect( audioUI, SIGNAL( moreReleased() ), this, SLOT( stopChangingVolume() ) ); + connect( audioUI, SIGNAL( lessReleased() ), this, SLOT( stopChangingVolume() ) ); +} + + +MediaPlayer::~MediaPlayer() { +} + + +void MediaPlayer::pauseCheck( bool b ) { + // Only pause if playing + if ( b && !mediaPlayerState->playing() ) + mediaPlayerState->setPaused( FALSE ); +} + + +void MediaPlayer::play() { + mediaPlayerState->setPlaying( FALSE ); + mediaPlayerState->setPlaying( TRUE ); +} + + +void MediaPlayer::setPlaying( bool play ) { + + if ( !play ) { + mediaPlayerState->setPaused( FALSE ); + loopControl->stop( FALSE ); + return; + } + + if ( mediaPlayerState->paused() ) { + mediaPlayerState->setPaused( FALSE ); + return; + } + + const DocLnk *playListCurrent = playList->current(); + + if ( playListCurrent != NULL ) { + loopControl->stop( TRUE ); + currentFile = playListCurrent; + } + + if ( currentFile == NULL ) { + QMessageBox::critical( 0, tr( "No file"), tr( "Error: There is no file selected" ) ); + mediaPlayerState->setPlaying( FALSE ); + return; + } + + if ( !QFile::exists( currentFile->file() ) ) { + QMessageBox::critical( 0, tr( "File not found"), tr( "The following file was not found: " ) + currentFile->file() + "" ); + mediaPlayerState->setPlaying( FALSE ); + return; + } + + if ( !mediaPlayerState->newDecoder( currentFile->file() ) ) { + QMessageBox::critical( 0, tr( "No decoder found"), tr( "Sorry, no appropriate decoders found for this file: " ) + currentFile->file() + "" ); + mediaPlayerState->setPlaying( FALSE ); + return; + } + + if ( !loopControl->init( currentFile->file() ) ) { + QMessageBox::critical( 0, tr( "Error opening file"), tr( "Sorry, an error occured trying to play the file: " ) + currentFile->file() + "" ); + mediaPlayerState->setPlaying( FALSE ); + return; + } + + long seconds = loopControl->totalPlaytime(); + QString time; time.sprintf("%li:%02i", seconds/60, (int)seconds%60 ); + QString tickerText = tr( " File: " ) + currentFile->name() + tr(", Length: ") + time; + QString fileInfo = mediaPlayerState->curDecoder()->fileInfo(); + if ( !fileInfo.isEmpty() ) + tickerText += ", " + fileInfo; + audioUI->setTickerText( tickerText + "." ); + + loopControl->play(); + + mediaPlayerState->setView( loopControl->hasVideo() ? 'v' : 'a' ); +} + + +void MediaPlayer::prev() { + if ( playList->prev() ) + play(); + else if ( mediaPlayerState->looping() ) { + if ( playList->last() ) + play(); + } else + mediaPlayerState->setList(); +} + + +void MediaPlayer::next() { + if ( playList->next() ) + play(); + else if ( mediaPlayerState->looping() ) { + if ( playList->first() ) + play(); + } else + mediaPlayerState->setList(); +} + + +void MediaPlayer::startDecreasingVolume() { + volumeDirection = -1; + startTimer( 100 ); + AudioDevice::decreaseVolume(); +} + + +void MediaPlayer::startIncreasingVolume() { + volumeDirection = +1; + startTimer( 100 ); + AudioDevice::increaseVolume(); +} + + +void MediaPlayer::stopChangingVolume() { + killTimers(); +} + + +void MediaPlayer::timerEvent( QTimerEvent * ) { + if ( volumeDirection == +1 ) + AudioDevice::increaseVolume(); + else if ( volumeDirection == -1 ) + AudioDevice::decreaseVolume(); +} + diff --git a/core/multimedia/opieplayer/mediaplayer.h b/core/multimedia/opieplayer/mediaplayer.h new file mode 100644 index 0000000..379d95c --- a/dev/null +++ b/core/multimedia/opieplayer/mediaplayer.h @@ -0,0 +1,59 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MEDIA_PLAYER_H +#define MEDIA_PLAYER_H + + +#include +#include +#include +#include "mediaplayerplugininterface.h" + + +class DocLnk; + + +class MediaPlayer : public QObject { + Q_OBJECT +public: + MediaPlayer( QObject *parent, const char *name ); + ~MediaPlayer(); + +private slots: + void setPlaying( bool ); + void pauseCheck( bool ); + void play(); + void next(); + void prev(); + void startIncreasingVolume(); + void startDecreasingVolume(); + void stopChangingVolume(); + +protected: + void timerEvent( QTimerEvent *e ); + +private: + int volumeDirection; + const DocLnk *currentFile; +}; + + +#endif // MEDIA_PLAYER_H + diff --git a/core/multimedia/opieplayer/mediaplayerplugininterface.h b/core/multimedia/opieplayer/mediaplayerplugininterface.h new file mode 100644 index 0000000..24d5a80 --- a/dev/null +++ b/core/multimedia/opieplayer/mediaplayerplugininterface.h @@ -0,0 +1,113 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MEDIA_PLAYER_PLUGIN_INTERFACE_H +#define MEDIA_PLAYER_PLUGIN_INTERFACE_H + +#include + +#ifndef QT_NO_COMPONENT +// {c0093632-b44c-4cf7-a279-d82fe8a8890c} +# ifndef IID_MediaPlayerPlugin +# define IID_MediaPlayerPlugin QUuid( 0xc0093632, 0xb44c, 0x4cf7, 0xa2, 0x79, 0xd8, 0x2f, 0xe8, 0xa8, 0x89, 0x0c ) +# endif +#endif + + +enum ColorFormat { + RGB565, + BGR565, + RGBA8888, + BGRA8888 +}; + + +class MediaPlayerDecoder { + +public: + virtual ~MediaPlayerDecoder() { }; + + // About Plugin + virtual const char *pluginName() = 0; + virtual const char *pluginComment() = 0; + virtual double pluginVersion() = 0; + + virtual bool isFileSupported( const QString& file ) = 0; + virtual bool open( const QString& file ) = 0; + virtual bool close() = 0; + virtual bool isOpen() = 0; + virtual const QString &fileInfo() = 0; + + // If decoder doesn't support audio then return 0 here + virtual int audioStreams() = 0; + virtual int audioChannels( int stream ) = 0; + virtual int audioFrequency( int stream ) = 0; + virtual int audioSamples( int stream ) = 0; + virtual bool audioSetSample( long sample, int stream ) = 0; + virtual long audioGetSample( int stream ) = 0; +// virtual bool audioReadMonoSamples( short *samples, long samples, long& samplesRead, int stream ) = 0; +// virtual bool audioReadStereoSamples( short *samples, long samples, long& samplesRead, int stream ) = 0; + virtual bool audioReadSamples( short *samples, int channels, long samples, long& samplesRead, int stream ) = 0; + // Libmpeg3 functions, perhaps good for reading an audio file with 5 channels or something! +// virtual bool audioReadSamples( short *samples, int channel, long samples, int stream ) = 0; +// virtual bool audioReReadSamples( short *samples, int channel, long samples, int stream ) = 0; + + // If decoder doesn't support video then return 0 here + virtual int videoStreams() = 0; + virtual int videoWidth( int stream ) = 0; + virtual int videoHeight( int stream ) = 0; + virtual double videoFrameRate( int stream ) = 0; // frames per second (this may change to frames/1000secs) + virtual int videoFrames( int stream ) = 0; + virtual bool videoSetFrame( long sample, int stream ) = 0; + virtual long videoGetFrame( int stream ) = 0; + virtual bool videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) = 0; + virtual bool videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) = 0; + virtual bool videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) = 0; + + // Profiling + virtual double getTime() = 0; + + // Ignore if these aren't supported + virtual bool setSMP( int cpus ) = 0; + virtual bool setMMX( bool useMMX ) = 0; + + // Capabilities + virtual bool supportsAudio() = 0; + virtual bool supportsVideo() = 0; + virtual bool supportsYUV() = 0; + virtual bool supportsMMX() = 0; + virtual bool supportsSMP() = 0; + virtual bool supportsStereo() = 0; + virtual bool supportsScaling() = 0; + +}; + + +class MediaPlayerEncoder; + + +struct MediaPlayerPluginInterface : public QUnknownInterface +{ + virtual MediaPlayerDecoder *decoder() = 0; + virtual MediaPlayerEncoder *encoder() = 0; +}; + + +#endif + diff --git a/core/multimedia/opieplayer/mediaplayerstate.cpp b/core/multimedia/opieplayer/mediaplayerstate.cpp new file mode 100644 index 0000000..9b9d133 --- a/dev/null +++ b/core/multimedia/opieplayer/mediaplayerstate.cpp @@ -0,0 +1,185 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "mediaplayerplugininterface.h" +#include "mediaplayerstate.h" + +#ifdef QT_NO_COMPONENT +// Plugins which are compiled in when no plugin architecture available +#include "libmad/libmadpluginimpl.h" +#include "libmpeg3/libmpeg3pluginimpl.h" +#include "wavplugin/wavpluginimpl.h" +#endif + + +//#define MediaPlayerDebug(x) qDebug x +#define MediaPlayerDebug(x) + + +MediaPlayerState::MediaPlayerState( QObject *parent, const char *name ) + : QObject( parent, name ), decoder( NULL ), libmpeg3decoder( NULL ) { + Config cfg( "MediaPlayer" ); + readConfig( cfg ); + loadPlugins(); +} + + +MediaPlayerState::~MediaPlayerState() { + Config cfg( "MediaPlayer" ); + writeConfig( cfg ); +} + + +void MediaPlayerState::readConfig( Config& cfg ) { + cfg.setGroup("Options"); + isFullscreen = cfg.readBoolEntry( "FullScreen" ); + isScaled = cfg.readBoolEntry( "Scaling" ); + isLooping = cfg.readBoolEntry( "Looping" ); + isShuffled = cfg.readBoolEntry( "Shuffle" ); + usePlaylist = cfg.readBoolEntry( "UsePlayList" ); + isPlaying = FALSE; + isPaused = FALSE; + curPosition = 0; + curLength = 0; + curView = 'l'; +} + + +void MediaPlayerState::writeConfig( Config& cfg ) const { + cfg.setGroup("Options"); + cfg.writeEntry("FullScreen", isFullscreen ); + cfg.writeEntry("Scaling", isScaled ); + cfg.writeEntry("Looping", isLooping ); + cfg.writeEntry("Shuffle", isShuffled ); + cfg.writeEntry("UsePlayList", usePlaylist ); +} + + +struct MediaPlayerPlugin { +#ifndef QT_NO_COMPONENT + QLibrary *library; +#endif + MediaPlayerPluginInterface *iface; + MediaPlayerDecoder *decoder; + MediaPlayerEncoder *encoder; +}; + + +static QValueList pluginList; + + +// Find the first decoder which supports this type of file +MediaPlayerDecoder *MediaPlayerState::newDecoder( const QString& file ) { + MediaPlayerDecoder *tmpDecoder = NULL; + QValueList::Iterator it; + for ( it = pluginList.begin(); it != pluginList.end(); ++it ) { + if ( (*it).decoder->isFileSupported( file ) ) { + tmpDecoder = (*it).decoder; + break; + } + } + return decoder = tmpDecoder; +} + + +MediaPlayerDecoder *MediaPlayerState::curDecoder() { + return decoder; +} + + +// ### hack to get true sample count +MediaPlayerDecoder *MediaPlayerState::libMpeg3Decoder() { + return libmpeg3decoder; +} + + +void MediaPlayerState::loadPlugins() { + +#ifndef QT_NO_COMPONENT + QValueList::Iterator mit; + for ( mit = pluginList.begin(); mit != pluginList.end(); ++mit ) { + (*mit).iface->release(); + (*mit).library->unload(); + delete (*mit).library; + } + pluginList.clear(); + + QString path = QPEApplication::qpeDir() + "/plugins/codecs"; + QDir dir( path, "lib*.so" ); + QStringList list = dir.entryList(); + QStringList::Iterator it; + for ( it = list.begin(); it != list.end(); ++it ) { + MediaPlayerPluginInterface *iface = 0; + QLibrary *lib = new QLibrary( path + "/" + *it ); + + MediaPlayerDebug(( "querying: %s", QString( path + "/" + *it ).latin1() )); + + if ( lib->queryInterface( IID_MediaPlayerPlugin, (QUnknownInterface**)&iface ) == QS_OK ) { + + MediaPlayerDebug(( "loading: %s", QString( path + "/" + *it ).latin1() )); + + MediaPlayerPlugin plugin; + plugin.library = lib; + plugin.iface = iface; + plugin.decoder = plugin.iface->decoder(); + plugin.encoder = plugin.iface->encoder(); + pluginList.append( plugin ); + + // ### hack to get true sample count + if ( plugin.decoder->pluginName() == QString("LibMpeg3Plugin") ) + libmpeg3decoder = plugin.decoder; + + } else { + delete lib; + } + } +#else + pluginList.clear(); + + MediaPlayerPlugin plugin0; + plugin0.iface = new LibMpeg3PluginImpl; + plugin0.decoder = plugin0.iface->decoder(); + plugin0.encoder = plugin0.iface->encoder(); + pluginList.append( plugin0 ); + + MediaPlayerPlugin plugin1; + plugin1.iface = new LibMadPluginImpl; + plugin1.decoder = plugin1.iface->decoder(); + plugin1.encoder = plugin1.iface->encoder(); + pluginList.append( plugin1 ); + + MediaPlayerPlugin plugin2; + plugin2.iface = new WavPluginImpl; + plugin2.decoder = plugin2.iface->decoder(); + plugin2.encoder = plugin2.iface->encoder(); + pluginList.append( plugin2 ); +#endif + + if ( pluginList.count() ) + MediaPlayerDebug(( "%i decoders found", pluginList.count() )); + else + MediaPlayerDebug(( "No decoders found" )); +} + diff --git a/core/multimedia/opieplayer/mediaplayerstate.h b/core/multimedia/opieplayer/mediaplayerstate.h new file mode 100644 index 0000000..5d95b92 --- a/dev/null +++ b/core/multimedia/opieplayer/mediaplayerstate.h @@ -0,0 +1,117 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MEDIA_PLAYER_STATE_H +#define MEDIA_PLAYER_STATE_H + + +#include + + +class MediaPlayerDecoder; +class Config; + + +class MediaPlayerState : public QObject { +Q_OBJECT +public: + MediaPlayerState( QObject *parent, const char *name ); + ~MediaPlayerState(); + + bool fullscreen() { return isFullscreen; } + bool scaled() { return isScaled; } + bool looping() { return isLooping; } + bool shuffled() { return isShuffled; } + bool playlist() { return usePlaylist; } + bool paused() { return isPaused; } + bool playing() { return isPlaying; } + long position() { return curPosition; } + long length() { return curLength; } + char view() { return curView; } + + MediaPlayerDecoder *newDecoder( const QString& file ); + MediaPlayerDecoder *curDecoder(); + MediaPlayerDecoder *libMpeg3Decoder(); // ### Yucky hack needed to use libmpeg3plugin to get the + // number of audio samples if we are using the libmad plugin +public slots: + void setFullscreen( bool b ) { if ( isFullscreen == b ) return; isFullscreen = b; emit fullscreenToggled(b); } + void setScaled( bool b ) { if ( isScaled == b ) return; isScaled = b; emit scaledToggled(b); } + void setLooping( bool b ) { if ( isLooping == b ) return; isLooping = b; emit loopingToggled(b); } + void setShuffled( bool b ) { if ( isShuffled == b ) return; isShuffled = b; emit shuffledToggled(b); } + void setPlaylist( bool b ) { if ( usePlaylist == b ) return; usePlaylist = b; emit playlistToggled(b); } + void setPaused( bool b ) { if ( isPaused == b ) return; isPaused = b; emit pausedToggled(b); } + void setPlaying( bool b ) { if ( isPlaying == b ) return; isPlaying = b; emit playingToggled(b); } + void setPosition( long p ) { if ( curPosition == p ) return; curPosition = p; emit positionChanged(p); } + void updatePosition( long p ){ if ( curPosition == p ) return; curPosition = p; emit positionUpdated(p); } + void setLength( long l ) { if ( curLength == l ) return; curLength = l; emit lengthChanged(l); } + void setView( char v ) { if ( curView == v ) return; curView = v; emit viewChanged(v); } + + void setPrev() { emit prev(); } + void setNext() { emit next(); } + void setList() { setPlaying( FALSE ); setView('l'); } + void setVideo() { setView('v'); } + void setAudio() { setView('a'); } + + void toggleFullscreen() { setFullscreen( !isFullscreen ); } + void toggleScaled() { setScaled( !isScaled); } + void toggleLooping() { setLooping( !isLooping); } + void toggleShuffled() { setShuffled( !isShuffled); } + void togglePlaylist() { setPlaylist( !usePlaylist); } + void togglePaused() { setPaused( !isPaused); } + void togglePlaying() { setPlaying( !isPlaying); } + +signals: + void fullscreenToggled( bool ); + void scaledToggled( bool ); + void loopingToggled( bool ); + void shuffledToggled( bool ); + void playlistToggled( bool ); + void pausedToggled( bool ); + void playingToggled( bool ); + void positionChanged( long ); // When the slider is moved + void positionUpdated( long ); // When the media file progresses + void lengthChanged( long ); + void viewChanged( char ); + + void prev(); + void next(); + +private: + bool isFullscreen; + bool isScaled; + bool isLooping; + bool isShuffled; + bool usePlaylist; + bool isPaused; + bool isPlaying; + long curPosition; + long curLength; + char curView; + + MediaPlayerDecoder *decoder; + MediaPlayerDecoder *libmpeg3decoder; + + void loadPlugins(); + void readConfig( Config& cfg ); + void writeConfig( Config& cfg ) const; +}; + + +#endif // MEDIA_PLAYER_STATE_H + diff --git a/core/multimedia/opieplayer/mpegplayer.pro b/core/multimedia/opieplayer/mpegplayer.pro new file mode 100644 index 0000000..d6952f8 --- a/dev/null +++ b/core/multimedia/opieplayer/mpegplayer.pro @@ -0,0 +1,21 @@ +TEMPLATE = app +CONFIG = qt warn_on release +DESTDIR = $(QPEDIR)/bin +HEADERS = loopcontrol.h mediaplayerplugininterface.h playlistselection.h mediaplayerstate.h \ + videowidget.h audiowidget.h playlistwidget.h mediaplayer.h audiodevice.h +SOURCES = main.cpp \ + loopcontrol.cpp playlistselection.cpp mediaplayerstate.cpp \ + videowidget.cpp audiowidget.cpp playlistwidget.cpp mediaplayer.cpp audiodevice.cpp +TARGET = mpegplayer +INCLUDEPATH += $(QPEDIR)/include +DEPENDPATH += $(QPEDIR)/include +LIBS += -lqpe -lpthread + +# INTERFACES = +# INCLUDEPATH += $(QPEDIR)/include +# CONFIG+=static +# TMAKE_CXXFLAGS += -DQPIM_STANDALONE +# LIBS += libmpeg3/libmpeg3.a -lpthread +# LIBS += $(QPEDIR)/plugins/codecs/liblibmadplugin.so + +TRANSLATIONS = ../i18n/de/mpegplayer.ts diff --git a/core/multimedia/opieplayer/playlistselection.cpp b/core/multimedia/opieplayer/playlistselection.cpp new file mode 100644 index 0000000..fbfb946 --- a/dev/null +++ b/core/multimedia/opieplayer/playlistselection.cpp @@ -0,0 +1,179 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "playlistselection.h" + +#include + + +class PlayListSelectionItem : public QListViewItem { +public: + PlayListSelectionItem( QListView *parent, const DocLnk *f ) : QListViewItem( parent ), fl( f ) { + setText( 0, f->name() ); + setPixmap( 0, f->pixmap() ); + } + + ~PlayListSelectionItem() { + }; + + const DocLnk *file() const { return fl; } + +private: + const DocLnk *fl; +}; + + +PlayListSelection::PlayListSelection( QWidget *parent, const char *name ) + : QListView( parent, name ) +{ +#ifdef USE_PLAYLIST_BACKGROUND + setStaticBackground( TRUE ); + setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/background" ) ); +#endif + setAllColumnsShowFocus( TRUE ); + addColumn( tr( "Playlist Selection" ) ); + header()->hide(); + setSorting( -1, FALSE ); +} + + +PlayListSelection::~PlayListSelection() { +} + + +#ifdef USE_PLAYLIST_BACKGROUND +void PlayListSelection::drawBackground( QPainter *p, const QRect &r ) { + p->fillRect( r, QBrush( white ) ); + QImage logo = Resource::loadImage( "mpegplayer/background" ); + if ( !logo.isNull() ) + p->drawImage( (width() - logo.width()) / 2, (height() - logo.height()) / 2, logo ); +} +#endif + + +void PlayListSelection::contentsMouseMoveEvent( QMouseEvent *event ) { + if ( event->state() == QMouseEvent::LeftButton ) { + QListViewItem *currentItem = selectedItem(); + QListViewItem *itemUnder = itemAt( QPoint( event->pos().x(), event->pos().y() - contentsY() ) ); + if ( currentItem && currentItem->itemAbove() == itemUnder ) + moveSelectedUp(); + else if ( currentItem && currentItem->itemBelow() == itemUnder ) + moveSelectedDown(); + } +} + + +const DocLnk *PlayListSelection::current() { + PlayListSelectionItem *item = (PlayListSelectionItem *)selectedItem(); + if ( item ) + return item->file(); + return NULL; +} + + +void PlayListSelection::addToSelection( const DocLnk &lnk ) { + PlayListSelectionItem *item = new PlayListSelectionItem( this, new DocLnk( lnk ) ); + QListViewItem *current = selectedItem(); + if ( current ) + item->moveItem( current ); + setSelected( item, TRUE ); + ensureItemVisible( selectedItem() ); +} + + +void PlayListSelection::removeSelected() { + QListViewItem *item = selectedItem(); + if ( item ) + delete item; + setSelected( currentItem(), TRUE ); + ensureItemVisible( selectedItem() ); +} + + +void PlayListSelection::moveSelectedUp() { + QListViewItem *item = selectedItem(); + if ( item && item->itemAbove() ) + item->itemAbove()->moveItem( item ); + ensureItemVisible( selectedItem() ); +} + + +void PlayListSelection::moveSelectedDown() { + QListViewItem *item = selectedItem(); + if ( item && item->itemBelow() ) + item->moveItem( item->itemBelow() ); + ensureItemVisible( selectedItem() ); +} + + +bool PlayListSelection::prev() { + QListViewItem *item = selectedItem(); + if ( item && item->itemAbove() ) + setSelected( item->itemAbove(), TRUE ); + else + return FALSE; + ensureItemVisible( selectedItem() ); + return TRUE; +} + + +bool PlayListSelection::next() { + QListViewItem *item = selectedItem(); + if ( item && item->itemBelow() ) + setSelected( item->itemBelow(), TRUE ); + else + return FALSE; + ensureItemVisible( selectedItem() ); + return TRUE; +} + + +bool PlayListSelection::first() { + QListViewItem *item = firstChild(); + if ( item ) + setSelected( item, TRUE ); + else + return FALSE; + ensureItemVisible( selectedItem() ); + return TRUE; +} + + +bool PlayListSelection::last() { + QListViewItem *prevItem = NULL; + QListViewItem *item = firstChild(); + while ( ( item = item->nextSibling() ) ) + prevItem = item; + if ( prevItem ) + setSelected( prevItem, TRUE ); + else + return FALSE; + ensureItemVisible( selectedItem() ); + return TRUE; +} + diff --git a/core/multimedia/opieplayer/playlistselection.h b/core/multimedia/opieplayer/playlistselection.h new file mode 100644 index 0000000..6ce6bdc --- a/dev/null +++ b/core/multimedia/opieplayer/playlistselection.h @@ -0,0 +1,62 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef PLAY_LIST_SELECTION_H +#define PLAY_LIST_SELECTION_H + + +#include +#include +#include + + +class PlayListSelection : public QListView { + Q_OBJECT +public: + PlayListSelection( QWidget *parent, const char *name=0 ); + ~PlayListSelection(); + + const DocLnk *current(); // retrieve the current playlist entry (media file link) + +public slots: + void addToSelection( const DocLnk & ); // Add a media file to the playlist + void removeSelected(); // Remove a media file from the playlist + void moveSelectedUp(); // Move the media file up the playlist so it is played earlier + void moveSelectedDown(); // Move the media file down the playlist so it is played later + bool prev(); + bool next(); + bool first(); + bool last(); + +protected: + virtual void contentsMouseMoveEvent(QMouseEvent *); +#ifdef USE_PLAYLIST_BACKGROUND + virtual void drawBackground( QPainter *p, const QRect &r ); + virtual void paintEmptyArea( QPainter *p, const QRect &r ) { drawBackground( p, r ); }; +#endif + +private: + QList selectedList; + const DocLnk *lnk; +}; + + +#endif // PLAY_LIST_SELECTION_H + + diff --git a/core/multimedia/opieplayer/playlistwidget.cpp b/core/multimedia/opieplayer/playlistwidget.cpp new file mode 100644 index 0000000..969fc4b --- a/dev/null +++ b/core/multimedia/opieplayer/playlistwidget.cpp @@ -0,0 +1,448 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "playlistselection.h" +#include "playlistwidget.h" +#include "mediaplayerstate.h" + +#include + + +extern MediaPlayerState *mediaPlayerState; + + +class PlayListWidgetPrivate { +public: + QToolButton *tbPlay; + QToolButton *tbFull; + QToolButton *tbLoop; + QToolButton *tbScale; + QToolButton *tbShuffle; + + QFrame *playListFrame; + FileSelector *files; + PlayListSelection *selectedFiles; + bool setDocumentUsed; + DocLnk *current; +}; + + +class ToolButton : public QToolButton { +public: + ToolButton( QWidget *parent, const char *name, const QString& icon, QObject *handler, const QString& slot, bool t = FALSE ) + : QToolButton( parent, name ) { + setTextLabel( name ); + setPixmap( Resource::loadPixmap( icon ) ); + setAutoRaise( TRUE ); + setFocusPolicy( QWidget::NoFocus ); + setToggleButton( t ); + connect( this, t ? SIGNAL( toggled(bool) ) : SIGNAL( clicked() ), handler, slot ); + QPEMenuToolFocusManager::manager()->addWidget( this ); + } +}; + + +class MenuItem : public QAction { +public: + MenuItem( QWidget *parent, const QString& text, QObject *handler, const QString& slot ) + : QAction( text, QString::null, 0, 0 ) { + connect( this, SIGNAL( activated() ), handler, slot ); + addTo( parent ); + } +}; + + +PlayListWidget::PlayListWidget( QWidget* parent, const char* name, WFlags fl ) + : QMainWindow( parent, name, fl ) { + + d = new PlayListWidgetPrivate; + d->setDocumentUsed = FALSE; + d->current = NULL; + + setBackgroundMode( PaletteButton ); + + setCaption( tr("MediaPlayer") ); + setIcon( Resource::loadPixmap( "MPEGPlayer" ) ); + + setToolBarsMovable( FALSE ); + + // Create Toolbar + QPEToolBar *toolbar = new QPEToolBar( this ); + toolbar->setHorizontalStretchable( TRUE ); + + // Create Menubar + QPEMenuBar *menu = new QPEMenuBar( toolbar ); + menu->setMargin( 0 ); + + QPEToolBar *bar = new QPEToolBar( this ); + bar->setLabel( tr( "Play Operations" ) ); +#ifdef BUTTONS_ON_TOOLBAR + d->tbPlay = new ToolButton( bar, tr( "Play" ), "mpegplayer/play", mediaPlayerState, SLOT(setPlaying(bool)), TRUE ); + d->tbShuffle = new ToolButton( bar, tr( "Randomize" ), "mpegplayer/shuffle", mediaPlayerState, SLOT(setShuffled(bool)), TRUE ); +#endif + d->tbLoop = new ToolButton( bar, tr( "Loop" ), "mpegplayer/loop", mediaPlayerState, SLOT(setLooping(bool)), TRUE ); + d->tbFull = new ToolButton( bar, tr( "Fullscreen" ), "fullscreen", mediaPlayerState, SLOT(setFullscreen(bool)), TRUE ); + d->tbScale = new ToolButton( bar, tr( "Scale" ), "mpegplayer/scale", mediaPlayerState, SLOT(setScaled(bool)), TRUE ); + + QPopupMenu *pmPlayList = new QPopupMenu( this ); + menu->insertItem( tr( "PlayList" ), pmPlayList ); + new MenuItem( pmPlayList, tr( "Toggle PlayList" ), mediaPlayerState, SLOT( togglePlaylist() ) ); + new MenuItem( pmPlayList, tr( "Clear List" ), this, SLOT( clearList() ) ); + new MenuItem( pmPlayList, tr( "Add all music files" ), this, SLOT( addAllMusicToList() ) ); + new MenuItem( pmPlayList, tr( "Add all video files" ), this, SLOT( addAllVideoToList() ) ); + new MenuItem( pmPlayList, tr( "Add all files" ), this, SLOT( addAllToList() ) ); +#ifdef CAN_SAVE_LOAD_PLAYLISTS + new MenuItem( pmPlayList, tr( "Save PlayList" ), this, SLOT( saveList() ) ); + new MenuItem( pmPlayList, tr( "Load PlayList" ), this, SLOT( loadList() ) ); +#endif + + QVBox *vbox5 = new QVBox( this ); vbox5->setBackgroundMode( PaletteButton ); + + // Add the playlist area + QVBox *vbox3 = new QVBox( vbox5 ); vbox3->setBackgroundMode( PaletteButton ); + d->playListFrame = vbox3; + + QLabel *plString = new QLabel( tr(" PlayList"), vbox3 ); + plString->setBackgroundMode( QButton::PaletteButton ); + plString->setFont( QFont( "Helvetica", 8, QFont::Bold ) ); + + QHBox *hbox2 = new QHBox( vbox3 ); hbox2->setBackgroundMode( PaletteButton ); + d->selectedFiles = new PlayListSelection( hbox2 ); + QVBox *vbox1 = new QVBox( hbox2 ); vbox1->setBackgroundMode( PaletteButton ); + +#ifndef BUTTONS_ON_TOOLBAR + d->tbPlay = new ToolButton( vbox1, tr( "Play" ), "mpegplayer/play", mediaPlayerState, SLOT(setPlaying(bool)), TRUE ); + QVBox *stretch1 = new QVBox( vbox1 ); stretch1->setBackgroundMode( PaletteButton ); // add stretch +#endif + new ToolButton( vbox1, tr( "Move Up" ), "mpegplayer/up", d->selectedFiles, SLOT(moveSelectedUp()) ); + new ToolButton( vbox1, tr( "Remove" ), "mpegplayer/cut", d->selectedFiles, SLOT(removeSelected()) ); + new ToolButton( vbox1, tr( "Move Down" ), "mpegplayer/down", d->selectedFiles, SLOT(moveSelectedDown()) ); + QVBox *stretch2 = new QVBox( vbox1 ); stretch2->setBackgroundMode( PaletteButton ); // add stretch +#ifndef BUTTONS_ON_TOOLBAR + d->tbShuffle = new ToolButton( vbox1, tr( "Randomize" ), "mpegplayer/shuffle", mediaPlayerState, SLOT(setShuffled(bool)), TRUE ); +#endif + + // add the library area + QVBox *vbox4 = new QVBox( vbox5 ); vbox4->setBackgroundMode( PaletteButton ); + + QLabel *libString = new QLabel( tr(" Media Library"), vbox4 ); + libString->setBackgroundMode( QButton::PaletteButton ); + libString->setFont( QFont( "Helvetica", 8, QFont::Bold ) ); + + QHBox *hbox6 = new QHBox( vbox4 ); hbox6->setBackgroundMode( PaletteButton ); + d->files = new FileSelector( "video/*;audio/*", hbox6, "Find Media Files", FALSE, FALSE ); + d->files->setBackgroundMode( PaletteButton ); + QVBox *vbox7 = new QVBox( hbox6 ); vbox7->setBackgroundMode( PaletteButton ); + +#ifdef SIDE_BUTTONS + new ToolButton( vbox7, tr( "Add to Playlist" ), "mpegplayer/add_to_playlist", d->selectedFiles, SLOT(addSelected()) ); + new ToolButton( vbox7, tr( "Remove from Playlist" ), "mpegplayer/remove_from_playlist", d->selectedFiles, SLOT(removeSelected()) ); + QVBox *stretch3 = new QVBox( vbox1 ); stretch3->setBackgroundMode( PaletteButton ); // add stretch +#endif + + connect( d->files, SIGNAL( fileSelected( const DocLnk & ) ), this, SLOT( addToSelection( const DocLnk & ) ) ); + connect( mediaPlayerState, SIGNAL( playingToggled( bool ) ), d->tbPlay, SLOT( setOn( bool ) ) ); + connect( mediaPlayerState, SIGNAL( loopingToggled( bool ) ), d->tbLoop, SLOT( setOn( bool ) ) ); + connect( mediaPlayerState, SIGNAL( shuffledToggled( bool ) ), d->tbShuffle, SLOT( setOn( bool ) ) ); + connect( mediaPlayerState, SIGNAL( fullscreenToggled( bool ) ), d->tbFull, SLOT( setOn( bool ) ) ); + connect( mediaPlayerState, SIGNAL( scaledToggled( bool ) ), d->tbScale, SLOT( setOn( bool ) ) ); + connect( mediaPlayerState, SIGNAL( fullscreenToggled( bool ) ), d->tbScale, SLOT( setEnabled( bool ) ) ); + connect( mediaPlayerState, SIGNAL( playlistToggled( bool ) ), this, SLOT( setPlaylist( bool ) ) ); + + setCentralWidget( vbox5 ); + + Config cfg( "MediaPlayer" ); + readConfig( cfg ); + + initializeStates(); +} + + +PlayListWidget::~PlayListWidget() { + Config cfg( "MediaPlayer" ); + writeConfig( cfg ); + + if ( d->current ) + delete d->current; + delete d; +} + + +void PlayListWidget::initializeStates() { + d->tbPlay->setOn( mediaPlayerState->playing() ); + d->tbLoop->setOn( mediaPlayerState->looping() ); + d->tbShuffle->setOn( mediaPlayerState->shuffled() ); + d->tbFull->setOn( mediaPlayerState->fullscreen() ); + d->tbScale->setOn( mediaPlayerState->scaled() ); + d->tbScale->setEnabled( mediaPlayerState->fullscreen() ); + setPlaylist( mediaPlayerState->playlist() ); +} + + +void PlayListWidget::readConfig( Config& cfg ) { + cfg.setGroup("PlayList"); + + int noOfFiles = cfg.readNumEntry("NumberOfFiles", 0 ); + + for ( int i = 0; i < noOfFiles; i++ ) { + QString entryName; + entryName.sprintf( "File%i", i + 1 ); + QString linkFile = cfg.readEntry( entryName ); + DocLnk lnk( linkFile ); + if ( lnk.isValid() ) + d->selectedFiles->addToSelection( lnk ); + + } +} + + +void PlayListWidget::writeConfig( Config& cfg ) const { + cfg.setGroup("PlayList"); + + int noOfFiles = 0; + + d->selectedFiles->first(); + do { + const DocLnk *lnk = d->selectedFiles->current(); + if ( lnk ) { + QString entryName; + entryName.sprintf( "File%i", noOfFiles + 1 ); + cfg.writeEntry( entryName, lnk->linkFile() ); + // if this link does exist, add it so we have the file + // next time... + if ( !QFile::exists( lnk->linkFile() ) ) { + // the way writing lnks doesn't really check for out + // of disk space, but check it anyway. + if ( !lnk->writeLink() ) { + QMessageBox::critical( 0, tr("Out of space"), + tr( "There was a problem saving " + "the playlist.\n" + "Your playlist " + "may be missing some entries\n" + "the next time you start it." ) + ); + } + } + noOfFiles++; + } + } while ( d->selectedFiles->next() ); + + cfg.writeEntry("NumberOfFiles", noOfFiles ); +} + + +void PlayListWidget::addToSelection( const DocLnk& lnk ) { + d->setDocumentUsed = FALSE; + if ( mediaPlayerState->playlist() ) + d->selectedFiles->addToSelection( lnk ); + else + mediaPlayerState->setPlaying( TRUE ); +} + + +void PlayListWidget::clearList() { + while ( first() ) + d->selectedFiles->removeSelected(); +} + + +void PlayListWidget::addAllToList() { + DocLnkSet files; + Global::findDocuments(&files, "video/*;audio/*"); + QListIterator dit( files.children() ); + for ( ; dit.current(); ++dit ) + d->selectedFiles->addToSelection( **dit ); +} + + +void PlayListWidget::addAllMusicToList() { + DocLnkSet files; + Global::findDocuments(&files, "audio/*"); + QListIterator dit( files.children() ); + for ( ; dit.current(); ++dit ) + d->selectedFiles->addToSelection( **dit ); +} + + +void PlayListWidget::addAllVideoToList() { + DocLnkSet files; + Global::findDocuments(&files, "video/*"); + QListIterator dit( files.children() ); + for ( ; dit.current(); ++dit ) + d->selectedFiles->addToSelection( **dit ); +} + + +void PlayListWidget::setDocument(const QString& fileref) { + if ( fileref.isNull() ) { + QMessageBox::critical( 0, tr( "Invalid File" ), tr( "There was a problem in getting the file." ) ); + return; + } + if ( mediaPlayerState->playlist() ) + addToSelection( DocLnk( fileref ) ); + else { + d->setDocumentUsed = TRUE; + if ( d->current ) + delete d->current; + d->current = new DocLnk( fileref ); + } + mediaPlayerState->setPlaying( FALSE ); + mediaPlayerState->setPlaying( TRUE ); +} + + +void PlayListWidget::setActiveWindow() { + // When we get raised we need to ensure that it switches views + char origView = mediaPlayerState->view(); + mediaPlayerState->setView( 'l' ); // invalidate + mediaPlayerState->setView( origView ); // now switch back +} + + +void PlayListWidget::useSelectedDocument() { + d->setDocumentUsed = FALSE; +} + + +const DocLnk *PlayListWidget::current() { + if ( mediaPlayerState->playlist() ) + return d->selectedFiles->current(); + else if ( d->setDocumentUsed && d->current ) { + return d->current; + } else + return d->files->selected(); +} + + +bool PlayListWidget::prev() { + if ( mediaPlayerState->playlist() ) { + if ( mediaPlayerState->shuffled() ) { + const DocLnk *cur = current(); + int j = 1 + (int)(97.0 * rand() / (RAND_MAX + 1.0)); + for ( int i = 0; i < j; i++ ) { + if ( !d->selectedFiles->next() ) + d->selectedFiles->first(); + } + if ( cur == current() ) + if ( !d->selectedFiles->next() ) + d->selectedFiles->first(); + return TRUE; + } else { + if ( !d->selectedFiles->prev() ) { + if ( mediaPlayerState->looping() ) { + return d->selectedFiles->last(); + } else { + return FALSE; + } + } + return TRUE; + } + } else { + return mediaPlayerState->looping(); + } +} + + +bool PlayListWidget::next() { + if ( mediaPlayerState->playlist() ) { + if ( mediaPlayerState->shuffled() ) { + return prev(); + } else { + if ( !d->selectedFiles->next() ) { + if ( mediaPlayerState->looping() ) { + return d->selectedFiles->first(); + } else { + return FALSE; + } + } + return TRUE; + } + } else { + return mediaPlayerState->looping(); + } +} + + +bool PlayListWidget::first() { + if ( mediaPlayerState->playlist() ) + return d->selectedFiles->first(); + else + return mediaPlayerState->looping(); +} + + +bool PlayListWidget::last() { + if ( mediaPlayerState->playlist() ) + return d->selectedFiles->last(); + else + return mediaPlayerState->looping(); +} + + +void PlayListWidget::saveList() { + QString filename; +// pseudo code +// filename = QLineEdit->getText(); + Config cfg( filename + ".playlist" ); + writeConfig( cfg ); +} + + +void PlayListWidget::loadList() { + QString filename; +// pseudo code +// filename = FileSelector->openFile( "*.playlist" ); + Config cfg( filename + ".playlist" ); + readConfig( cfg ); +} + + +void PlayListWidget::setPlaylist( bool shown ) { + if ( shown ) + d->playListFrame->show(); + else + d->playListFrame->hide(); +} + + +void PlayListWidget::setView( char view ) { + if ( view == 'l' ) + showMaximized(); + else + hide(); +} + diff --git a/core/multimedia/opieplayer/playlistwidget.h b/core/multimedia/opieplayer/playlistwidget.h new file mode 100644 index 0000000..6976641 --- a/dev/null +++ b/core/multimedia/opieplayer/playlistwidget.h @@ -0,0 +1,68 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef PLAY_LIST_WIDGET_H +#define PLAY_LIST_WIDGET_H + + +#include +#include + + +class PlayListWidgetPrivate; +class Config; + + +class PlayListWidget : public QMainWindow { + Q_OBJECT +public: + PlayListWidget( QWidget* parent=0, const char* name=0, WFlags fl=0 ); + ~PlayListWidget(); + + // retrieve the current playlist entry (media file link) + const DocLnk *current(); + void useSelectedDocument(); + +public slots: + void setDocument( const QString& fileref ); + void addToSelection( const DocLnk& ); // Add a media file to the playlist + void setActiveWindow(); // need to handle this to show the right view + void setPlaylist( bool ); // Show/Hide the playlist + void setView( char ); + void clearList(); + void addAllToList(); + void addAllMusicToList(); + void addAllVideoToList(); + void saveList(); // Save the playlist + void loadList(); // Load a playlist + bool first(); + bool last(); + bool next(); + bool prev(); + +private: + void initializeStates(); + void readConfig( Config& cfg ); + void writeConfig( Config& cfg ) const; + PlayListWidgetPrivate *d; // Private implementation data +}; + + +#endif // PLAY_LIST_WIDGET_H + diff --git a/core/multimedia/opieplayer/qpe-mpegplayer.control b/core/multimedia/opieplayer/qpe-mpegplayer.control new file mode 100644 index 0000000..2cad8ab --- a/dev/null +++ b/core/multimedia/opieplayer/qpe-mpegplayer.control @@ -0,0 +1,9 @@ +Files: bin/mpegplayer pics/mpegplayer/* apps/Applications/mpegplayer.desktop plugins/codecs/libmpeg3plugin.so plugins/codecs/libmpeg3plugin.so.1 plugins/codecs/libmpeg3plugin.so.1.0 plugins/codecs/libmpeg3plugin.so.1.0.0 +Priority: optional +Section: qpe/applications +Maintainer: John Ryland +Architecture: arm +Version: $QPE_VERSION-3 +Depends: qpe-base ($QPE_VERSION) +Description: MPEG video/audio player + The mpegplayer for the Qtopia environment. diff --git a/core/multimedia/opieplayer/videowidget.cpp b/core/multimedia/opieplayer/videowidget.cpp new file mode 100644 index 0000000..f3974a0 --- a/dev/null +++ b/core/multimedia/opieplayer/videowidget.cpp @@ -0,0 +1,423 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "videowidget.h" +#include "mediaplayerplugininterface.h" +#include "mediaplayerstate.h" + + +#ifdef Q_WS_QWS +# define USE_DIRECT_PAINTER +# include +# include +#endif + + +extern MediaPlayerState *mediaPlayerState; + + +static const int xo = 2; // movable x offset +static const int yo = 0; // movable y offset + + +struct MediaButton { + int xPos, yPos; + bool isToggle, isHeld, isDown; + int controlType; +}; + + +// Layout information for the videoButtons (and if it is a toggle button or not) +MediaButton videoButtons[] = { + { 5+0*32+xo, 200+yo, FALSE, FALSE, FALSE, 4 }, // previous + { 5+1*32+xo, 200+yo, FALSE, FALSE, FALSE, 1 }, // stop + { 5+2*32+xo, 200+yo, TRUE, FALSE, FALSE, 0 }, // play + { 5+3*32+xo, 200+yo, TRUE, FALSE, FALSE, 2 }, // pause + { 5+4*32+xo, 200+yo, FALSE, FALSE, FALSE, 3 }, // next + { 5+5*32+xo, 200+yo, FALSE, FALSE, FALSE, 8 }, // playlist + { 5+6*32+xo, 200+yo, TRUE, FALSE, FALSE, 9 } // fullscreen +}; + + +static const int numButtons = (sizeof(videoButtons)/sizeof(MediaButton)); + + +VideoWidget::VideoWidget(QWidget* parent, const char* name, WFlags f) : + QWidget( parent, name, f ), scaledWidth( 0 ), scaledHeight( 0 ) { + setCaption( tr("MediaPlayer") ); + setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) ); + pixmaps[0] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButton0a" ) ); + pixmaps[1] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButton0b" ) ); + pixmaps[2] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaControls0" ) ); + currentFrame = new QImage( 220 + 2, 160, (QPixmap::defaultDepth() == 16) ? 16 : 32 ); + + slider = new QSlider( Qt::Horizontal, this ); + slider->setMinValue( 0 ); + slider->setMaxValue( 1 ); + slider->setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) ); + slider->setFocusPolicy( QWidget::NoFocus ); + slider->setGeometry( QRect( 7, 250, 220, 20 ) ); + + connect( slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) ); + connect( slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) ); + + connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) ); + connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) ); + connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) ); + connect( mediaPlayerState, SIGNAL( viewChanged(char) ), this, SLOT( setView(char) ) ); + connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( setPaused(bool) ) ); + connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) ); + + // Intialise state + setLength( mediaPlayerState->length() ); + setPosition( mediaPlayerState->position() ); + setFullscreen( mediaPlayerState->fullscreen() ); + setPaused( mediaPlayerState->paused() ); + setPlaying( mediaPlayerState->playing() ); +} + + +VideoWidget::~VideoWidget() { + for ( int i = 0; i < 3; i++ ) + delete pixmaps[i]; + delete currentFrame; +} + + +static bool videoSliderBeingMoved = FALSE; + + +void VideoWidget::sliderPressed() { + videoSliderBeingMoved = TRUE; +} + + +void VideoWidget::sliderReleased() { + videoSliderBeingMoved = FALSE; + if ( slider->width() == 0 ) + return; + long val = long((double)slider->value() * mediaPlayerState->length() / slider->width()); + mediaPlayerState->setPosition( val ); +} + + +void VideoWidget::setPosition( long i ) { + updateSlider( i, mediaPlayerState->length() ); +} + + +void VideoWidget::setLength( long max ) { + updateSlider( mediaPlayerState->position(), max ); +} + + +void VideoWidget::setView( char view ) { + if ( view == 'v' ) { + makeVisible(); + } else { + // Effectively blank the view next time we show it so it looks nicer + scaledWidth = 0; + scaledHeight = 0; + hide(); + } +} + + +void VideoWidget::updateSlider( long i, long max ) { + // Will flicker too much if we don't do this + if ( max == 0 ) + return; + int width = slider->width(); + int val = int((double)i * width / max); + if ( !mediaPlayerState->fullscreen() && !videoSliderBeingMoved ) { + if ( slider->value() != val ) + slider->setValue( val ); + if ( slider->maxValue() != width ) + slider->setMaxValue( width ); + } +} + + +void VideoWidget::setToggleButton( int i, bool down ) { + if ( down != videoButtons[i].isDown ) + toggleButton( i ); +} + + +void VideoWidget::toggleButton( int i ) { + videoButtons[i].isDown = !videoButtons[i].isDown; + QPainter p(this); + paintButton ( &p, i ); +} + + +void VideoWidget::paintButton( QPainter *p, int i ) { + int x = videoButtons[i].xPos; + int y = videoButtons[i].yPos; + int offset = 10 + videoButtons[i].isDown; + p->drawPixmap( x, y, *pixmaps[videoButtons[i].isDown] ); + p->drawPixmap( x + 1 + offset, y + offset, *pixmaps[2], 9 * videoButtons[i].controlType, 0, 9, 9 ); +} + + +void VideoWidget::mouseMoveEvent( QMouseEvent *event ) { + for ( int i = 0; i < numButtons; i++ ) { + int x = videoButtons[i].xPos; + int y = videoButtons[i].yPos; + if ( event->state() == QMouseEvent::LeftButton ) { + // The test to see if the mouse click is inside the circular button or not + // (compared with the radius squared to avoid a square-root of our distance) + int radius = 16; + QPoint center = QPoint( x + radius, y + radius ); + QPoint dXY = center - event->pos(); + int dist = dXY.x() * dXY.x() + dXY.y() * dXY.y(); + bool isOnButton = dist <= (radius * radius); + if ( isOnButton != videoButtons[i].isHeld ) { + videoButtons[i].isHeld = isOnButton; + toggleButton(i); + } + } else { + if ( videoButtons[i].isHeld ) { + videoButtons[i].isHeld = FALSE; + if ( !videoButtons[i].isToggle ) + setToggleButton( i, FALSE ); + switch (i) { + case VideoPlay: mediaPlayerState->setPlaying(videoButtons[i].isDown); return; + case VideoStop: mediaPlayerState->setPlaying(FALSE); return; + case VideoPause: mediaPlayerState->setPaused(videoButtons[i].isDown); return; + case VideoNext: mediaPlayerState->setNext(); return; + case VideoPrevious: mediaPlayerState->setPrev(); return; + case VideoPlayList: mediaPlayerState->setList(); return; + case VideoFullscreen: mediaPlayerState->setFullscreen( TRUE ); makeVisible(); return; + } + } + } + } +} + + +void VideoWidget::mousePressEvent( QMouseEvent *event ) { + mouseMoveEvent( event ); +} + + +void VideoWidget::mouseReleaseEvent( QMouseEvent *event ) { + if ( mediaPlayerState->fullscreen() ) { + mediaPlayerState->setFullscreen( FALSE ); + makeVisible(); + } else { + mouseMoveEvent( event ); + } +} + + +void VideoWidget::makeVisible() { + if ( mediaPlayerState->fullscreen() ) { + setBackgroundMode( QWidget::NoBackground ); + showFullScreen(); + resize( qApp->desktop()->size() ); + slider->hide(); + } else { + setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) ); + showNormal(); + showMaximized(); + slider->show(); + } +} + + +void VideoWidget::paintEvent( QPaintEvent * ) { + QPainter p( this ); + + if ( mediaPlayerState->fullscreen() ) { + // Clear the background + p.setBrush( QBrush( Qt::black ) ); + p.drawRect( rect() ); + + // Draw the current frame + //p.drawImage( ); // If using directpainter we won't have a copy except whats on the screen + } else { + // draw border + qDrawShadePanel( &p, 4, 15, 230, 170, colorGroup(), TRUE, 5, NULL ); + + // Clear the movie screen first + p.setBrush( QBrush( Qt::black ) ); + p.drawRect( 9, 20, 220, 160 ); + + // draw current frame (centrally positioned from scaling to maintain aspect ratio) + p.drawImage( 9 + (220 - scaledWidth) / 2, 20 + (160 - scaledHeight) / 2, *currentFrame, 0, 0, scaledWidth, scaledHeight ); + + // draw the buttons + for ( int i = 0; i < numButtons; i++ ) + paintButton( &p, i ); + + // draw the slider + slider->repaint( TRUE ); + } +} + + +void VideoWidget::closeEvent( QCloseEvent* ) { + mediaPlayerState->setList(); +} + + +bool VideoWidget::playVideo() { + bool result = FALSE; + + int stream = 0; + + int sw = mediaPlayerState->curDecoder()->videoWidth( stream ); + int sh = mediaPlayerState->curDecoder()->videoHeight( stream ); + int dd = QPixmap::defaultDepth(); + int w = height(); + int h = width(); + + ColorFormat format = (dd == 16) ? RGB565 : BGRA8888; + + if ( mediaPlayerState->fullscreen() ) { +#ifdef USE_DIRECT_PAINTER + QDirectPainter p(this); + + if ( ( qt_screen->transformOrientation() == 3 ) && + ( ( dd == 16 ) || ( dd == 32 ) ) && ( p.numRects() == 1 ) ) { + + w = 320; + h = 240; + + if ( mediaPlayerState->scaled() ) { + // maintain aspect ratio + if ( w * sh > sw * h ) + w = sw * h / sh; + else + h = sh * w / sw; + } else { + w = sw; + h = sh; + } + + w--; // we can't allow libmpeg to overwrite. + QPoint roff = qt_screen->mapToDevice( p.offset(), QSize( qt_screen->width(), qt_screen->height() ) ); + + int ox = roff.x() - height() + 2 + (height() - w) / 2; + int oy = roff.y() + (width() - h) / 2; + int sx = 0, sy = 0; + + uchar* fp = p.frameBuffer() + p.lineStep() * oy; + fp += dd * ox / 8; + uchar **jt = new uchar*[h]; + for ( int i = h; i; i-- ) { + jt[h - i] = fp; + fp += p.lineStep(); + } + + result = mediaPlayerState->curDecoder()->videoReadScaledFrame( jt, sx, sy, sw, sh, w, h, format, 0) == 0; + + delete [] jt; + } else { +#endif + QPainter p(this); + + w = 320; + h = 240; + + if ( mediaPlayerState->scaled() ) { + // maintain aspect ratio + if ( w * sh > sw * h ) + w = sw * h / sh; + else + h = sh * w / sw; + } else { + w = sw; + h = sh; + } + + int bytes = ( dd == 16 ) ? 2 : 4; + QImage tempFrame( w, h, bytes << 3 ); + result = mediaPlayerState->curDecoder()->videoReadScaledFrame( tempFrame.jumpTable(), + 0, 0, sw, sh, w, h, format, 0) == 0; + if ( result && mediaPlayerState->fullscreen() ) { + + int rw = h, rh = w; + QImage rotatedFrame( rw, rh, bytes << 3 ); + + ushort* in = (ushort*)tempFrame.bits(); + ushort* out = (ushort*)rotatedFrame.bits(); + int spl = rotatedFrame.bytesPerLine() / bytes; + for (int x=0; x sw * h ) + w = sw * h / sh; + else + h = sh * w / sw; + + result = mediaPlayerState->curDecoder()->videoReadScaledFrame( currentFrame->jumpTable(), 0, 0, sw, sh, w, h, format, 0) == 0; + + QPainter p( this ); + + // Image changed size, therefore need to blank the possibly unpainted regions first + if ( scaledWidth != w || scaledHeight != h ) { + p.setBrush( QBrush( Qt::black ) ); + p.drawRect( 9, 20, 220, 160 ); + } + + scaledWidth = w; + scaledHeight = h; + + if ( result ) { + p.drawImage( 9 + (220 - scaledWidth) / 2, 20 + (160 - scaledHeight) / 2, *currentFrame, 0, 0, scaledWidth, scaledHeight ); + } + + } + + return result; +} + + diff --git a/core/multimedia/opieplayer/videowidget.h b/core/multimedia/opieplayer/videowidget.h new file mode 100644 index 0000000..8b49091 --- a/dev/null +++ b/core/multimedia/opieplayer/videowidget.h @@ -0,0 +1,88 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef VIDEO_WIDGET_H +#define VIDEO_WIDGET_H + + +#include + + +class QPixmap; +class QSlider; + + +enum VideoButtons { + VideoPrevious, + VideoStop, + VideoPlay, + VideoPause, + VideoNext, + VideoPlayList, + VideoFullscreen +}; + + +class VideoWidget : public QWidget { + Q_OBJECT +public: + VideoWidget( QWidget* parent=0, const char* name=0, WFlags f=0 ); + ~VideoWidget(); + + bool playVideo(); + +public slots: + void updateSlider( long, long ); + void sliderPressed( ); + void sliderReleased( ); + void setPaused( bool b) { setToggleButton( VideoPause, b ); } + void setPlaying( bool b) { setToggleButton( VideoPlay, b ); } + void setFullscreen( bool b ) { setToggleButton( VideoFullscreen, b ); } + void makeVisible(); + void setPosition( long ); + void setLength( long ); + void setView( char ); + +signals: + void sliderMoved( long ); + +protected: + void paintEvent( QPaintEvent *pe ); + void mouseMoveEvent( QMouseEvent *event ); + void mousePressEvent( QMouseEvent *event ); + void mouseReleaseEvent( QMouseEvent *event ); + void closeEvent( QCloseEvent *event ); + +private: + void paintButton( QPainter *p, int i ); + void toggleButton( int ); + void setToggleButton( int, bool ); + + QSlider *slider; + QPixmap *pixmaps[3]; + QImage *currentFrame; + int scaledWidth; + int scaledHeight; +}; + + +#endif // VIDEO_WIDGET_H + + + diff --git a/core/multimedia/opieplayer/wavplugin/.cvsignore b/core/multimedia/opieplayer/wavplugin/.cvsignore new file mode 100644 index 0000000..6fe2396 --- a/dev/null +++ b/core/multimedia/opieplayer/wavplugin/.cvsignore @@ -0,0 +1,2 @@ +moc_* +Makefile diff --git a/core/multimedia/opieplayer/wavplugin/Makefile.in b/core/multimedia/opieplayer/wavplugin/Makefile.in new file mode 100644 index 0000000..c9203f8 --- a/dev/null +++ b/core/multimedia/opieplayer/wavplugin/Makefile.in @@ -0,0 +1,112 @@ +############################################################################# + +####### Compiler, tools and options + +CXX = $(SYSCONF_CXX) $(QT_CXX_MT) +CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) -DQCONFIG=\"qpe\" +CC = $(SYSCONF_CC) $(QT_C_MT) +CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) -DQCONFIG=\"qpe\" +INCPATH = -I$(QPEDIR)/include -I.. +LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) +LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP) +MOC = $(SYSCONF_MOC) +UIC = $(SYSCONF_UIC) + +####### Target + +DESTDIR = ../../plugins/codecs/ +VER_MAJ = 1 +VER_MIN = 0 +VER_PATCH = 0 +TARGET = wavplugin +TARGET1 = lib$(TARGET).so.$(VER_MAJ) + +####### Files + +HEADERS = wavplugin.h \ + wavpluginimpl.h +SOURCES = wavplugin.cpp \ + wavpluginimpl.cpp +OBJECTS = wavplugin.o \ + wavpluginimpl.o +INTERFACES = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = + + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + + +all: $(DESTDIR)$(SYSCONF_LINK_TARGET) + +$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) + $(SYSCONF_LINK_LIB) + +moc: $(SRCMOC) + +tmake: + tmake wavplugin.pro + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) + -rm -f *~ core + -rm -f allmoc.cpp + +####### Extension Modules + +listpromodules: + @echo + +listallmodules: + @echo + +listaddonpromodules: + @echo + +listaddonentmodules: + @echo + + +REQUIRES= + +####### Sub-libraries + + +###### Combined headers + + + +####### Compile + +wavplugin.o: wavplugin.cpp \ + wavplugin.h \ + ../mediaplayerplugininterface.h + +wavpluginimpl.o: wavpluginimpl.cpp \ + wavplugin.h \ + ../mediaplayerplugininterface.h \ + wavpluginimpl.h \ + ../mediaplayerplugininterface.h + + diff --git a/core/multimedia/opieplayer/wavplugin/qpe-wavplugin.control b/core/multimedia/opieplayer/wavplugin/qpe-wavplugin.control new file mode 100644 index 0000000..8e7eedb --- a/dev/null +++ b/core/multimedia/opieplayer/wavplugin/qpe-wavplugin.control @@ -0,0 +1,9 @@ +Files: plugins/codecs/libwavplugin.so.1.0.0 plugins/codecs/libwavplugin.so.1.0 plugins/codecs/libwavplugin.so.1 plugins/codecs/libwavplugin.so +Priority: optional +Section: qpe/plugins +Maintainer: John Ryland +Architecture: arm +Version: $QPE_VERSION-3 +Depends: qpe-base ($QPE_VERSION) +Description: WAV file plugin + Plugin to play WAV files with the mediaplayer in the Qtopia environment. diff --git a/core/multimedia/opieplayer/wavplugin/wavplugin.cpp b/core/multimedia/opieplayer/wavplugin/wavplugin.cpp new file mode 100644 index 0000000..60a0024 --- a/dev/null +++ b/core/multimedia/opieplayer/wavplugin/wavplugin.cpp @@ -0,0 +1,334 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "wavplugin.h" + + +//#define debugMsg(a) qDebug(a) +#define debugMsg(a) + + +struct RiffChunk { + char id[4]; + Q_UINT32 size; + char data[4]; +}; + + +struct ChunkData { + Q_INT16 formatTag; + Q_INT16 channels; + Q_INT32 samplesPerSec; + Q_INT32 avgBytesPerSec; + Q_INT16 blockAlign; + Q_INT16 wBitsPerSample; +}; + + +const int sound_buffer_size = 4096; + + +class WavPluginData { +public: + QFile *input; + + int wavedata_remaining; + ChunkData chunkdata; + RiffChunk chunk; + uchar data[sound_buffer_size+32]; // +32 to handle badly aligned input data + int out,max; + int samples_due; + int samples; + + WavPluginData() { + max = out = sound_buffer_size; + wavedata_remaining = 0; + samples_due = 0; + samples = -1; + } + + // expands out samples to the frequency of 44kHz + bool add( short *output, long count, long& done, bool stereo ) + { + done = 0; + + if ( input == 0 ) { + qDebug("no input"); + return FALSE; + } + + while ( count ) { + int l,r; + if ( getSample(l, r) == FALSE ) { + qDebug("didn't get sample"); + return FALSE; + } + samples_due += 44100; + while ( count && (samples_due > chunkdata.samplesPerSec) ) { + *output++ = l; + if ( stereo ) + *output++ = r; + samples_due -= chunkdata.samplesPerSec; + count--; + done++; + } + } + + return TRUE; + } + + bool initialise() { + if ( input == 0 ) + return FALSE; + + wavedata_remaining = -1; + + while ( wavedata_remaining == -1 ) { + // Keep reading chunks... + const int n = sizeof(chunk) - sizeof(chunk.data); + int t = input->readBlock( (char*)&chunk, n ); + if ( t != n ) { + if ( t == -1 ) + return FALSE; + return TRUE; + } + if ( qstrncmp(chunk.id,"data",4) == 0 ) { + samples = wavedata_remaining = chunk.size; + } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) { + char d[4]; + if ( input->readBlock(d,4) != 4 ) { + return FALSE; + } + if ( qstrncmp(d,"WAVE",4) != 0 ) { + // skip + if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size-4) ) { + return FALSE; + } + } + } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) { + if ( input->readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) { + return FALSE; + } +#define WAVE_FORMAT_PCM 1 + if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) { + qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag); + return FALSE; + } + } else { + // ignored chunk + if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size) ) { + return FALSE; + } + } + } // while + + return TRUE; + } + + + // gets a sample from the file + bool getSample(int& l, int& r) + { + l = r = 0; + + if ( input == 0 ) + return FALSE; + + if ( (wavedata_remaining < 0) || !max ) + return FALSE; + + if ( out >= max ) { + max = input->readBlock( (char*)data, (uint)QMIN(sound_buffer_size,wavedata_remaining) ); + + wavedata_remaining -= max; + + out = 0; + if ( max <= 0 ) { + max = 0; + return TRUE; + } + } + if ( chunkdata.wBitsPerSample == 8 ) { + l = (data[out++] - 128) * 128; + } else { + l = ((short*)data)[out/2]; + out += 2; + } + if ( chunkdata.channels == 1 ) { + r = l; + } else { + if ( chunkdata.wBitsPerSample == 8 ) { + r = (data[out++] - 128) * 128; + } else { + r = ((short*)data)[out/2]; + out += 2; + } + } + return TRUE; + } // getSample + +}; + + +WavPlugin::WavPlugin() { + d = new WavPluginData; + d->input = 0; +} + + +WavPlugin::~WavPlugin() { + close(); + delete d; +} + + +bool WavPlugin::isFileSupported( const QString& path ) { + debugMsg( "WavPlugin::isFileSupported" ); + + char *ext = strrchr( path.latin1(), '.' ); + + // Test file extension + if ( ext ) { + if ( strncasecmp(ext, ".raw", 4) == 0 ) + return TRUE; + if ( strncasecmp(ext, ".wav", 4) == 0 ) + return TRUE; + if ( strncasecmp(ext, ".wave", 4) == 0 ) + return TRUE; + } + + return FALSE; +} + + +bool WavPlugin::open( const QString& path ) { + debugMsg( "WavPlugin::open" ); + + d->max = d->out = sound_buffer_size; + d->wavedata_remaining = 0; + d->samples_due = 0; + + d->input = new QFile( path ); + if ( d->input->open(IO_ReadOnly) == FALSE ) { + qDebug("couldn't open file"); + delete d->input; + d->input = 0; + return FALSE; + } + + d->initialise(); + + return TRUE; +} + + +bool WavPlugin::close() { + debugMsg( "WavPlugin::close" ); + + d->input->close(); + delete d->input; + d->input = 0; + return TRUE; +} + + +bool WavPlugin::isOpen() { + debugMsg( "WavPlugin::isOpen" ); + return ( d->input != 0 ); +} + + +int WavPlugin::audioStreams() { + debugMsg( "WavPlugin::audioStreams" ); + return 1; +} + + +int WavPlugin::audioChannels( int ) { + debugMsg( "WavPlugin::audioChannels" ); + return 2; // ### Always scale audio to stereo samples +} + + +int WavPlugin::audioFrequency( int ) { + debugMsg( "WavPlugin::audioFrequency" ); + return 44100; // ### Always scale to frequency of 44100 +} + + +int WavPlugin::audioSamples( int ) { + debugMsg( "WavPlugin::audioSamples" ); + return d->samples * 2 / d->chunkdata.channels; // ### Scaled samples will be made stereo, + // Therefore if source is mono we will double the number of samples +} + + +bool WavPlugin::audioSetSample( long, int ) { + debugMsg( "WavPlugin::audioSetSample" ); + return FALSE; +} + + +long WavPlugin::audioGetSample( int ) { + debugMsg( "WavPlugin::audioGetSample" ); + return 0; +} + +/* +bool WavPlugin::audioReadSamples( short *, int, long, int ) { + debugMsg( "WavPlugin::audioReadSamples" ); + return FALSE; +} + + +bool WavPlugin::audioReReadSamples( short *, int, long, int ) { + debugMsg( "WavPlugin::audioReReadSamples" ); + return FALSE; +} + + +bool WavPlugin::audioReadMonoSamples( short *output, long samples, long& samplesMade, int ) { + debugMsg( "WavPlugin::audioReadMonoSamples" ); + return !d->add( output, samples, samplesMade, FALSE ); +} + + +bool WavPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) { + debugMsg( "WavPlugin::audioReadStereoSamples" ); + return !d->add( output, samples, samplesMade, TRUE ); +} +*/ + +bool WavPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesMade, int ) { + debugMsg( "WavPlugin::audioReadSamples" ); + return !d->add( output, samples, samplesMade, channels != 1 ); +} + +double WavPlugin::getTime() { + debugMsg( "WavPlugin::getTime" ); + return 0.0; +} + + diff --git a/core/multimedia/opieplayer/wavplugin/wavplugin.h b/core/multimedia/opieplayer/wavplugin/wavplugin.h new file mode 100644 index 0000000..64635ca --- a/dev/null +++ b/core/multimedia/opieplayer/wavplugin/wavplugin.h @@ -0,0 +1,97 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef WAV_PLUGIN_H +#define WAV_PLUGIN_H + + +#include +#include +#include "mediaplayerplugininterface.h" + + +class WavPluginData; + + +class WavPlugin : public MediaPlayerDecoder { + +public: + WavPlugin(); + ~WavPlugin(); + + const char *pluginName() { return "WavPlugin"; } + const char *pluginComment() { return "This is a simple plugin for playing wav files"; } + double pluginVersion() { return 1.0; } + + bool isFileSupported( const QString& ); + bool open( const QString& ); + bool close(); + bool isOpen(); + //const QString &fileInfo() { return strInfo = qApp->translate( "MediaPlayer", "No Information Available", "media plugin text" ); } + const QString &fileInfo() { return strInfo = QString(""); } + + // If decoder doesn't support audio then return 0 here + int audioStreams(); + int audioChannels( int stream ); + int audioFrequency( int stream ); + int audioSamples( int stream ); + bool audioSetSample( long sample, int stream ); + long audioGetSample( int stream ); + //bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ); + //bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ); + bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ); + //bool audioReadSamples( short *output, int channel, long samples, int stream ); + //bool audioReReadSamples( short *output, int channel, long samples, int stream ); + + // If decoder doesn't support video then return 0 here + int videoStreams() { return 0; } + int videoWidth( int ) { return 0; } + int videoHeight( int ) { return 0; } + double videoFrameRate( int ) { return 0.0; } + int videoFrames( int ) { return 0; } + bool videoSetFrame( long, int ) { return FALSE; } + long videoGetFrame( int ) { return 0; } + bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; } + bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; } + bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; } + + // Profiling + double getTime(); + + // Ignore if these aren't supported + bool setSMP( int ) { return FALSE; } + bool setMMX( bool ) { return FALSE; } + + // Capabilities + bool supportsAudio() { return TRUE; } + bool supportsVideo() { return FALSE; } + bool supportsYUV() { return FALSE; } + bool supportsMMX() { return TRUE; } + bool supportsSMP() { return FALSE; } + bool supportsStereo() { return TRUE; } + bool supportsScaling() { return FALSE; } + +private: + WavPluginData *d; + QString strInfo; + +}; + + +#endif diff --git a/core/multimedia/opieplayer/wavplugin/wavplugin.pro b/core/multimedia/opieplayer/wavplugin/wavplugin.pro new file mode 100644 index 0000000..4663813 --- a/dev/null +++ b/core/multimedia/opieplayer/wavplugin/wavplugin.pro @@ -0,0 +1,10 @@ +TEMPLATE = lib +CONFIG += qt warn_on release +HEADERS = wavplugin.h wavpluginimpl.h +SOURCES = wavplugin.cpp wavpluginimpl.cpp +TARGET = wavplugin +DESTDIR = ../../plugins/codecs +INCLUDEPATH += $(QPEDIR)/include .. +DEPENDPATH += ../$(QPEDIR)/include .. +LIBS += -lqpe +VERSION = 1.0.0 diff --git a/core/multimedia/opieplayer/wavplugin/wavpluginimpl.cpp b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.cpp new file mode 100644 index 0000000..1f7b85b --- a/dev/null +++ b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.cpp @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "wavplugin.h" +#include "wavpluginimpl.h" + + +WavPluginImpl::WavPluginImpl() + : libmadplugin(0), ref(0) +{ +} + + +WavPluginImpl::~WavPluginImpl() +{ + if ( libmadplugin ) + delete libmadplugin; +} + + +MediaPlayerDecoder *WavPluginImpl::decoder() +{ + if ( !libmadplugin ) + libmadplugin = new WavPlugin; + return libmadplugin; +} + + +MediaPlayerEncoder *WavPluginImpl::encoder() +{ + return NULL; +} + + +#ifndef QT_NO_COMPONENT + + +QRESULT WavPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) ) + *iface = this, (*iface)->addRef(); + return QS_OK; +} + + +Q_EXPORT_INTERFACE() +{ + Q_CREATE_INSTANCE( WavPluginImpl ) +} + + +#endif + diff --git a/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h new file mode 100644 index 0000000..ee32f54 --- a/dev/null +++ b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef WAV_PLUGIN_IMPL_H +#define WAV_PLUGIN_IMPL_H + + +#include "../mediaplayerplugininterface.h" + + +class WavPlugin; + + +class WavPluginImpl : public MediaPlayerPluginInterface +{ +public: + WavPluginImpl(); + virtual ~WavPluginImpl(); + +#ifndef QT_NO_COMPONENT + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT + +#endif + + virtual MediaPlayerDecoder *decoder(); + virtual MediaPlayerEncoder *encoder(); + +private: + WavPlugin *libmadplugin; + ulong ref; +}; + + +#endif + -- cgit v0.9.0.2